在云那方

首页 新随笔 联系 订阅 管理
最近开放平台非常火,各大互联网公司都纷纷推出各自的开放平台,随之流行的 OpenID, OAuth 则成为认证和授权的主要技术。本文将以登陆新浪微博获得授权取得用户数据作为示例简单研究 OAuth 的使用。(OAuth WIKI)。现在.net上开源的OAuth的框架有不少了。比如:
DotNetOpenAuth  (不知道怎么回事,最近这个网站不太好上)
OAuth.Net
DevDefined.OAuth
看了看源代码和帮助文档,比较了下,选了 DevDefined.OAuth 来作为本篇示例的 OAuth 框架,因为它简单容易上手。
(PS:OAuth 最新的版本是2.0但现在大多数网站还只是支持 1.0)

先看看 OAuth 的授权流程图:

为了帮助理解,先定义3个角色:1.最终用户,2.应用程序(消费方), 3.服务(授权方)。那么根据 OAuth 定义主要过程如下:
(1) 【用户】使用【应用程序】,【应用程序】提示【用户】需要授权,【应用程序】先向【服务】获取:RequestToken
(2) 【应用程序】带着 RequestToken 和指定的 Callback  跳转到 【服务】端,让【用户】输入用户名和密码进行授权
(3) 授权成功后,【服务】端则会跳转到【应用程序】提供的Callback页面上,【应用程序】获取:AccessToken
(4) 接下来,【应用程序】用 AccessToken 从【服务】端获取【用户】在【服务】上的各种数据
OK,下面来看看如何使用新浪微博的OAuth,首先当然你需要去申请一个新浪应用的 AppKey 和 AppSecret

新浪的 OAuth 的官方文档:http://open.weibo.com/wiki/index.php/Oauth

【准备】
1. 添加 DevDefined.OAuth.dll
2. 将 RequestUrl, AccessUrl, UserAuthorizeUrl 以及 AppKey, AppSecret 定义在 Project Settings 中


 【应用页面入口】

按下 Click 获得 RequestToken 跳转到新浪授权页面:

  1. protected void oauthRequest_Click(object sender, EventArgs e)  
  2. {  
  3.     var session = OAuthSessionFactory.CreateSession();  
  4.     var requestToken = session.GetRequestToken();  
  5.     if (string.IsNullOrEmpty(requestToken.Token))  
  6.     {  
  7.         throw new Exception("The request token was null or empty");  
  8.     }  
  9.     Session[requestToken.Token] = requestToken;  
  10.     var callback = "http://localhost:" + HttpContext.Current.Request.Url.Port + "/Callback.ashx";  
  11.     var authorizationUrl = session.GetUserAuthorizationUrlForToken(requestToken, callback);  
  12.     Response.Redirect(authorizationUrl, true);  
  13. }  

 

Fiddler 拦截的Request内容:
GET http://api.t.sina.com.cn/oauth/request_token?oauth_callback=oob&oauth_nonce=99119f7f-ace7-45d4-86b5-31ddd092ca86&oauth_consumer_key=[SinaAppKey]&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1311492533&oauth_version=1.0&oauth_signature=[Signature] HTTP/1.1
说明:[SinaAppKey] 是申请的应用程序Key, [Signature]是根据 BaseUrl 使用 HMAC-SHA1 和 SinaAppSecret 生成的签名。后面的请求无论是用 GET 还是 POST,都类似。


授权之后,跳转到 Callback 页面上:这里 Callback 用 ashx 开发。Callback 被服务端 Request 的时候,从 Request 里能取到 oauth_token,oauth_verifier
  1. public partial class Callback : System.Web.IHttpHandler, System.Web.SessionState.IRequiresSessionState  
  2. {  
  3.     public void ProcessRequest(System.Web.HttpContext context)  
  4.     {  
  5.         var session = OAuthSessionFactory.CreateSession();  
  6.         var requestTokenString = context.Request["oauth_token"];  
  7.         var oauthVerifier = context.Request["oauth_verifier"];  
  8.         var user_id = "";  
  9.         var requestToken = (IToken)context.Session[requestTokenString];  
  10.         session.ResponseBodyAction = body => {  
  11.             // 交换完AccessToken后,会返回user_id,用正则表达式取出   
  12.             user_id = Regex.Match(body, "user_id=(.*)").Groups[1].Value;  
  13.         };                       
  14.         IToken accessToken = session.ExchangeRequestTokenForAccessToken(requestToken, oauthVerifier);  
  15.         context.Session[requestTokenString] = null;  
  16.         context.Session["acess_token"] = accessToken;  
  17.         context.Session["user_id"] = user_id;             
  18.          
  19.         context.Response.Redirect("Welcome.aspx");  
  20.     }  
  21. }  
在 Welcome.aspx 页面中,获取用户的个人信息:
  1. public partial class Weclome : System.Web.UI.Page  
  2. {  
  3.     protected void Page_Load(object sender, EventArgs e)  
  4.     {  
  5.         if (!IsPostBack)  
  6.         {  
  7.             IToken accessToken = Session["acess_token"as IToken;  
  8.             var userId = Session["user_id"as string;  
  9.   
  10.             // 使用OAuth时不用传AppKey   
  11.             var showUserUrl = string.Format("http://api.t.sina.com.cn/users/show/{0}.json", userId);  
  12.             var session = OAuthSessionFactory.CreateSession();  
  13.             session.AccessToken = accessToken;  
  14.             try  
  15.             {  
  16.                 var resp = session.Request().Get().ForUrl(showUserUrl).SignWithToken().ToWebResponse();  
  17.                 using (var sr = new StreamReader(resp.GetResponseStream()))  
  18.                 {  
  19.                     var json = sr.ReadToEnd();  
  20.                     var userInfo = JsonConvert.DeserializeObject<SinaWeiboUser>(json);  
  21.                     detailUserInfo.DataSource = new List<SinaWeiboUser> { userInfo };  
  22.                     detailUserInfo.DataBind();  
  23.                 }                     
  24.             }  
  25.             catch (WebException webEx)  
  26.             {  
  27.                 var resp = (HttpWebResponse)webEx.Response;  
  28.                 using (var sr = new StreamReader(resp.GetResponseStream()))  
  29.                 {  
  30.                     Response.Write(sr.ReadToEnd());  
  31.                 }  
  32.             }  
  33.  
  34.             #region By WebClient Request   
  35.                 //var client = new WebClient();   
  36.                 //var customerOAuthContext = new OAuthConsumerContext   
  37.                 //{   
  38.                 //    ConsumerKey = Properties.Settings.Default.SinaAppKey,   
  39.                 //    ConsumerSecret = Properties.Settings.Default.SinaAppSecret,   
  40.                 //    SignatureMethod = SignatureMethod.HmacSha1,   
  41.                 //    UseHeaderForOAuthParameters = true,   
  42.                 //};   
  43.                 //var oauthContext = new OAuthContext()   
  44.                 //{   
  45.                 //    RawUri = new Uri(showUserUrl),   
  46.                 //    RequestMethod = "GET",   
  47.                 //};   
  48.                 //customerOAuthContext.SignContextWithToken(oauthContext, accessToken);   
  49.                 //var token = string.Format(",oauth_token=\"{0}\"", accessToken.Token);   
  50.                 //client.Headers[Parameters.OAuth_Authorization_Header] = oauthContext.GenerateOAuthParametersForHeader() + token;   
  51.                 //client.Encoding = System.Text.Encoding.UTF8;   
  52.                 //var json = client.DownloadString(showUserUrl);   
  53.                 //var userInfo = JsonConvert.DeserializeObject<SinaWeiboUser>(json);   
  54.                 //detailUserInfo.DataSource = new List<SinaWeiboUser> { userInfo };   
  55.                 //detailUserInfo.DataBind();  
  56.                 #endregion   
  57.         }  
  58.     }  
  59. }  
用 oauth_accesstoken 访问 http://api.t.sina.com.cn/users/show/{0}.json{0}用用户Id替换,请求json的api,用json.net 反序列化绑定到 DetailForm 控件上。
代码下载:http://download.csdn.net/source/3482263
posted on 2011-11-25 12:39  Rich.T  阅读(695)  评论(0编辑  收藏  举报