http://stackoverflow.com/questions/12499602/body-joints-angle-using-kinect?rq=1

新浪微博跟update相关的api已经挂了很多天了一直没有恢复正常,返回错误:40070 Error limited application access api!,新浪开放平台的论坛里n多的人都在等这个恢复,新浪官方也相当的恶心出问题了连个公告都没有,既不说什么原因又不说什么时候能恢复,。还是有版主说是api正在升级礼拜1恢复正常今天都礼拜2了还是不行。基于这个原因我的android版的新浪微博客户端已经停工好几天了,刚好是跟update相关的一些功能。

客户端开发不成了,就自己做做服务端程序,提供类似新浪微博rest api服务, api其实说简单也很简单了,无法是通过链接对外提供json或者xml格式的数据和接收外部提供的数据进去相应的存储、删除、更新等操作。过程中碰到的最麻烦的问题就是OAuth认证功能了,在做android版的新浪微博客户端时候也花了蛮长的时间对OAuth认证进行研究,在客户端原先是采用了oauth-signpost开源项目,后来由于某些原因就放弃了这个开源类库,自己重新写了OAuth认证部分的实现, 现在做服务端的OAuth认证,其实有过做客户端的经验做服务端也差不多,简单的说无非是客户端对参数字符串进行签名然后把签名值传输到服务端,服务端也对同样对参数字符串进行签名,把从客户端传过来的签名值进去比较,简单的说就这么个过程,具体实现肯定比这个要复杂多了,不明真相的同学可以google一下OAuth进行深入的学习研究了。

服务端程序用asp.net和C#编写了而非java,理由很简单本人对.net更加熟悉。由于想快速的实现效果采用了oauth-dot-net开源项目并没有全部自己写。

一、首先新建名为Rest Api的ASP.NET Web应用程序,然后添加 oauth-dot-net开源项目相关的几个dll(Castle.Core.dll、Castle.MicroKernel.dll、Castle.Windsor.dll、CommonServiceLocator.WindsorAdapter.dll、Microsoft.Practices.ServiceLocation.dll、OAuth.Net.Common.dll、OAuth.Net.Components.dll、OAuth.Net.ServiceProvider.dll)。

二、在Web.config文件里添加相应的配置,具体可以参考OAuth.Net.Examples.EchoServiceProvider项目,然后在Global.asax.cs添加如下代码:


public override void Init()
        {
            IServiceLocator injector =
                new WindsorServiceLocator(
                    new WindsorContainer(
                        new XmlInterpreter(
                            new ConfigResource("oauth.net.components"))));             ServiceLocator.SetLocatorProvider(() => injector);

}

接下来是比较重要,就是request_token、authorize、access_token的实现,OAuth认证实现的几个过程,不理解可以看android开发我的新浪微博客户端-OAuth篇(2.1) ,具体代码实现很多是参考OAuth.Net.Examples.EchoServiceProvider示例项目。

三、 首先新建ConsumerStore.cs类,用来存储Consumer信息,由于测试项目所以存储在内存中并没有考虑保存到数据库,真实项目的时候请把相应的Consumer信息保存到数据库中。Consumer信息对应新浪微博其实就是应用的App Key和App Secret,当开发者在新浪微博建一个新的应用获取App Key和App Secret,所以完整的应该还需要一个开发一个提供给第三方开发者申请获取App Key和App Secret的功能页面,这里就不具体实现,直接在代码里写死了一个名为测试应用的Consumer,App Key:2433927322,App Secret:87f042c9e8183cbde0f005a00db1529f,这个提供给客户端测试用。 具体代码如下:


public sealed class ConsumerStore : InMemoryConsumerStore, IConsumerStore
    {
        internal static readonly IConsumer FixedConsumer = new OAuthConsumer("2433927322", "87f042c9e8183cbde0f005a00db1529f", "测试应用", ConsumerStatus.Valid);         public ConsumerStore()
        {
            this.ConsumerDictionary.Add(
                ConsumerStore.FixedConsumer.Key, 
                ConsumerStore.FixedConsumer);
        }         public override bool Add(IConsumer consumer)
        {
            throw new NotSupportedException("Consumers cannot be added to this store--it is fixed.");
        }         public override bool Contains(string consumerKey)
        {
            return ConsumerStore.FixedConsumer.Key.Equals(consumerKey);
        }         public override bool Update(IConsumer consumer)
        {
            throw new NotSupportedException("Consumers cannot be updated in this store--it is fixed.");
        }         public override bool Remove(IConsumer consumer)
        {
            throw new NotSupportedException("Consumers cannot be removed from this store--it is fixed.");
        }

}

四、接下来就是request_token功能,新建RequestTokenHandler.cs ,这个是OAuth.Net.ServiceProvider.RequestTokenHandler子类,并且是httpHandlers所以需要在Web.config中添加httpHandlers配置,这个用来接收客户端程序的请求,返回给客户端程序Request Token和Request Secret用,具体代码如下:


public sealed class RequestTokenHandler : OAuth.Net.ServiceProvider.RequestTokenHandler
    {   
        protected override void IssueRequestToken(HttpContext httpContext, OAuthRequestContext requestContext)
        {
            //产生RequestToken
            IRequestToken token = this.GenerateRequestToken(httpContext, requestContext);             requestContext.RequestToken = token;
            Uri callbackUri;
            if (Uri.TryCreate(requestContext.Parameters.Callback, UriKind.Absolute, out callbackUri))
            {
                if (!ServiceProviderContext.CallbackStore.ContainsCallback(token))
                {
                    //保存Callback地址了
                    ServiceProviderContext.CallbackStore.AddCallback(token, callbackUri);
                }
            }
            else
                OAuthRequestException.ThrowParametersRejected(new string[] { Constants.CallbackParameter }, "Not a valid Uri.");             //把token.Token和token.Secret输出到客户端,
            requestContext.ResponseParameters[Constants.TokenParameter] = token.Token;
            requestContext.ResponseParameters[Constants.TokenSecretParameter] = token.Secret;
        }         protected override IRequestToken GenerateRequestToken(HttpContext httpContext, OAuthRequestContext requestContext)
        {
            
            return ServiceProviderContext.TokenGenerator.CreateRequestToken(requestContext.Consumer, requestContext.Parameters);
        }

}

五、 接着是authorize功能,新建名为authorize.aspx的页面,用来给用户输入账号和密码进行授权的页面,这个页面很简单具体如下图,在这个页面中获取用户输入的账户和密码跟数据库中存储的用户账号和密码进行验证,如果验证通过返回之前客户端提供的callback地址,并且给这个地址添加一个校验码,具体代码如下:


public partial class authorize : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {         }         protected void Button1_Click(object sender, EventArgs e)
        {
            if (loginName.Text == "test" && password.Text == "123")
            {
                string toke = Request.Params["oauth_token"];
                IRequestToken tk = ServiceProviderContext.TokenStore.GetRequestToken(toke);
                Uri callback = ServiceProviderContext.CallbackStore.GetCalback(tk);
                string oauth_verifier = ServiceProviderContext.VerificationProvider.Generate(tk);
                Response.Redirect(callback.ToString() + "?oauth_verifier=" + oauth_verifier);
            }
            
        }

}

六、接下来就是access_token功能,新建AccessTokenHandler.cs , 这个是OAuth.Net.ServiceProvider.AccessTokenHandler子类,并且是httpHandlers所以需要在Web.config中添加httpHandlers配置,这个用来接收客户端程序的请求,返回给客户端程序Access Token和Access Secret用,具体代码如下:


public sealed class AccessTokenHandler : OAuth.Net.ServiceProvider.AccessTokenHandler
    {
        protected override void IssueAccessToken(HttpContext httpContext, OAuthRequestContext requestContext)
        {
            //产生access token
            IAccessToken accessToken = this.GenerateAccessToken(httpContext, requestContext);             accessToken.Status = TokenStatus.Authorized;             // 把accessToken和accessSecret输出到客户端,
            requestContext.ResponseParameters[Constants.TokenParameter] = accessToken.Token;
            requestContext.ResponseParameters[Constants.TokenSecretParameter] = accessToken.Secret;
        }         protected override IAccessToken GenerateAccessToken(HttpContext httpContext,  OAuthRequestContext requestContext)
        {
            return ServiceProviderContext.TokenGenerator.CreateAccessToken(requestContext.Consumer, requestContext.RequestToken);
        }
    } public class TokenGenerator : ITokenGenerator
    {
        internal static readonly IRequestToken FixedRequestToken = new OAuthRequestToken("requestkey",
            "requestsecret",
            ConsumerStore.FixedConsumer,
            TokenStatus.Authorized,
            null,
            ServiceProviderContext.DummyIdentity,
            new string[] { });         internal static readonly IAccessToken FixedAccessToken = new OAuthAccessToken(
            "accesskey",
            "accesssecret",
            ConsumerStore.FixedConsumer,
            TokenStatus.Authorized,
            TokenGenerator.FixedRequestToken);         public IRequestToken CreateRequestToken(IConsumer consumer, OAuthParameters parameters)
        {
            return TokenGenerator.FixedRequestToken;
        }         public IAccessToken CreateAccessToken(IConsumer consumer, IRequestToken requestToken)
        {
            return TokenGenerator.FixedAccessToken;
        }
    } public class TokenStore : InMemoryTokenStore, ITokenStore
    {
        public TokenStore()
        {
            this.RequestTokenDictionary.Add(
                TokenGenerator.FixedRequestToken.Token,
                TokenGenerator.FixedRequestToken);             this.AccessTokenDictionary.Add(
                TokenGenerator.FixedAccessToken.Token,
                TokenGenerator.FixedAccessToken);
        }         public override bool Add(IRequestToken token)
        {
            throw new NotSupportedException("Tokens cannot be added to the token store--it is fixed.");
        }         public override bool Add(IAccessToken token)
        {
            throw new NotSupportedException("Tokens cannot be added to the token store--it is fixed.");
        }         public override bool Update(IRequestToken token)
        {
            throw new NotSupportedException("Tokens cannot be updated in the token store--it is fixed.");
        }         public override bool Update(IAccessToken token)
        {
            throw new NotSupportedException("Tokens cannot be updated in the token store--it is fixed.");
        }         public override bool Remove(IRequestToken token)
        {
            throw new NotSupportedException("Tokens cannot be removed from the token store--it is fixed.");
        }         public override bool Remove(IAccessToken token)
        {
            throw new NotSupportedException("Tokens cannot be removed from the token store--it is fixed.");
        }

}

这样就完成了一个最最简单小型的服务端OAuth认证,然后用android客户端进行测试ok通过。

注意点:

一、android模拟器访问本地服务地址为10.0.2.2,比如http://localhost:3423/authorize.aspx在模拟器中用http://10.0.2.2:3423/authorize.aspx。

二、OAuth.Net类库的OAuth.Net.Common项目中的interface ICallbackStore 添加了一个Uri GetCalback(IRequestToken token);并且在具体的实现类InMemoryCallbackStore添加了实习代码:

public Uri GetCalback(IRequestToken token)

        {
            lock (this.callbackStore)
            {
                if (this.callbackStore.ContainsKey(token))
                {
                    return this.callbackStore[token];
                }
                else
                {
                    return null;
                }
            }
        }
 

三、为了能用我前面做的给新浪用的android客户端,对于类库源代码AccessTokenHandler的ParseParameters方法做了如下修改,因为新浪请求api的时候都会加一个source的参数:

protected virtual void ParseParameters(HttpContext httpContext, OAuthRequestContext requestContext)

        {
            .......
            parameters.AllowOnly(
                    Constants.ConsumerKeyParameter,
                    Constants.TokenParameter,
                    Constants.SignatureMethodParameter,
                    Constants.SignatureParameter,
                    Constants.TimestampParameter,
                    Constants.NonceParameter,
                    Constants.VerifierParameter,
                    Constants.VersionParameter, // (optional)
                    Constants.RealmParameter, // (optional)
                    "source");
 
            ......
        }
 

服务端API的OAuth认证实现的更多相关文章

  1. .Net分布式异常报警系统-客户端及服务端API

    客户端 客户端的作用就是捕获未处理异常, 发送异常到服务端. 关于捕获未处理异常的方法参考 http://www.cnblogs.com/youring2/archive/2012/04/25/246 ...

  2. 安卓推送——个推服务端api使用误区

    首先你需要在个推开放着平台上注册你的应用,以及获得以下几个必要的值APPID |APPKEY | MASTERSECRET,本文假设你已经完成上述步骤以及完成客户端SDK的集成. 原理 个推服务端ap ...

  3. Identity4实现服务端+api资源控制+客户端请求

    准备写一些关于Identity4相关的东西,最近也比较对这方面感兴趣.所有做个开篇笔记记录一下,以便督促自己下一个技术方案方向 已经写好的入门级别Identity4的服务+api资源访问控制和简单的客 ...

  4. JAVA通过http访问其他服务端API

    项目要实现这么一个功能,用户通过点击按钮,通过axios来访问python的API(算法,java不好做)得到一个结果存储到数据库并且返回到页面. 但是python不是在tomcat上面运行的,所以不 ...

  5. 服务端API 工作经验(没有工作的是体会不到的)

    1.慢慢了解以下内容 [{xx:xxx,xx:xxx},{xx:xxx,xx:xxx},{xx:xxx,xx:xxx},]-- 数据 data 服务端API 状态代码(01代表成功) message ...

  6. CMDB学习之五服务端api

    服务端api 对发送来的数据进行处理,并返回结果,首先要创建一个Django项目 第一步,就是写URL路由在分支中写url api 主路由 from django.conf.urls import u ...

  7. C#开发BIMFACE系列6 服务端API之获取文件信息

    在<C#开发BIMFACE系列4 服务端API之源上传文件>.<C#开发BIMFACE系列5 服务端API之文件直传>两篇文章中详细介绍了如何将本地文件上传到BIMFACE服务 ...

  8. C#开发BIMFACE系列4 服务端API之源上传文件

    在注册成为BIMFACE的应用开发者后,要能在浏览器里浏览你的模型或者获取你模型内的BIM数据, 首先需要把你的模型文件上传到BIMFACE.根据不同场景,BIMFACE提供了丰富的文件相关的接口. ...

  9. C#开发BIMFACE系列3 服务端API之获取应用访问凭证AccessToken

    系列目录     [已更新最新开发文章,点击查看详细] BIMFACE 平台为开发者提供了大量的服务器端 API 与 JavaScript API,用于二次开发 BIM 的相关应用. BIMFACE ...

随机推荐

  1. VS2012编译Snmp++ v3.2.25

    VS2012编译Snmp++ v3.2.25跟用VC6/VC2010等编译方法区别不大. 网上和教程上盛传的方式是把snmp++的cpp源文件和头文件都加到工程里,再编译.我觉得添加所有头文件到工程里 ...

  2. TCP 协议三次握手过程解析带实例

    TCP(Transmission Control Protocol) 传输控制协议 TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接: 位码即tcp标志位,有6种标 ...

  3. uva10815 by sixleaves

    题目很简单.其实stringstream就的用法和iosteam差不多,所以学习起来是很简单的.stringstream类里面有一个string缓存,str()和str(string)成员函数.前者用 ...

  4. Codeforces 148D Bag of mice 概率dp(水

    题目链接:http://codeforces.com/problemset/problem/148/D 题意: 原来袋子里有w仅仅白鼠和b仅仅黑鼠 龙和王妃轮流从袋子里抓老鼠. 谁先抓到白色老师谁就赢 ...

  5. Hadoop基础

    Hadoop组成 包括两个核心组成:HDFS:分布式文件系统,存储海量的数据MapReduce:并行处理框架,实现任务分解和调度 搭建大型数据仓库,PB级数据的存储.处理.分析.统计等业务(搜索引擎. ...

  6. ZCTF-ARM64-Re300

    Re300-arm64     是一个64位的ARM程序.使用IDA加载,蹦出来这个框框,就是说IDA6.6还没有对ARM64位的程序实现relocation的分析.     就是由于这个,所以连对l ...

  7. JQuery EasyUi 扩展combox验证

    随笔记录一下 1.通过select text的值验证 /** * 扩展combox验证,easyui原始只验证select text的值,不支持value验证() */ (function($){ c ...

  8. css单位和值

    css需要单位来度量.内含整数.小数.百分数的情况,很多条件下支持正负的情况,当然是有限制的了.百分数基本是相对于自身.或是父或是祖先元素的某个属性值. 颜色         颜色的表示分为:命名颜色 ...

  9. 记一次phpStudy apache启动后自动关闭 修改过程

    第一种可能原因:路径包含中文 .添加站点 2.重启服务 3.遇见问题 apache 刚启动,1秒钟中后就停止 4.解决问题 发现是自己添加的网站中包含中文路径的问题,建议不要在自己的网站目录下包含中文 ...

  10. HDU 1021 - Fibonacci Again

    找规律,分析让 F[N] 每一项对 3 取余的余数: 1,2,0, 2,2,1,0, 1,1,2,0, 2,2,1,0, 1,1,2,0, 2,2,1,0 ......... 显然循环了 #inclu ...