使用DotNetOpenAuth搭建OAuth2.0授權框架——Demo代碼簡單說明


前段時間隨意抽離了一部分代碼作為OAuth2的示例代碼,若干處會造成困擾,現說明如下:

 1 public class OAuthController : Controller
 2     {
 3         private static string _authorizeUrl = ConfigurationManager.AppSettings["AuthorizeUrl"];
 4         private static string[] _queryParameters = new string[] { "client_id", "redirect_uri", "state", "response_type", "scope" };
 5         private readonly AuthorizationServer _authorizationServer = new AuthorizationServer(new OAuth2AuthorizationServer());
 6         
 7         [AcceptVerbs(HttpVerbs.Get)]
 8         public ActionResult Authorize(string userkey)
 9         {
10             var pendingRequest = this._authorizationServer.ReadAuthorizationRequest(Request);
11             if (pendingRequest == null)
12             {
13                 throw new HttpException((int)HttpStatusCode.BadRequest, "Missing authorization request.");
14             }
15 
16             if (string.IsNullOrEmpty(userkey))
17             {
18                 string url = _authorizeUrl, callback = Request.Url.GetLeftPart(UriPartial.Path);
19                 StringBuilder querystring = new StringBuilder(string.Format("client_id={0}&", HttpUtility.UrlEncode(this.Request.QueryString["client_id"]))), callbackQuery = new StringBuilder();
20                 foreach (string key in this.Request.QueryString.Keys)
21                 {
22                     if (!_queryParameters.Contains(key))
23                         querystring.Append(string.Format("{0}={1}&", key, HttpUtility.UrlEncode(this.Request.QueryString[key])));
24                     else
25                         callbackQuery.Append(string.Format("{0}={1}&", key, HttpUtility.UrlEncode(this.Request.QueryString[key])));
26                 }
27                 if (callbackQuery.Length > 0)
28                 {
29                     callback += ("?" + callbackQuery.ToString().TrimEnd('&'));
30                     querystring.Append(string.Format("callback={0}&", HttpUtility.UrlEncode(callback)));
31                 }
32                 if (querystring.Length > 0)
33                 {
34                     url += ("?" + querystring.ToString().TrimEnd('&'));
35                 }
36                 return Redirect(url);
37             }
38             else
39             {
40                 using (var db = new OAuthDbContext())
41                 {
42                     var client = db.Clients.FirstOrDefault(o => o.ClientIdentifier == pendingRequest.ClientIdentifier);
43                     if (client == null)
44                         throw new AuthorizeException("40143", "不受信任的商戶");
45                     else
46                     {
47                         var user = DESCrypt.Decrypt(userkey, client.ClientSecret);
48                         var approval = this._authorizationServer.PrepareApproveAuthorizationRequest(pendingRequest, user);
49                         var response = this._authorizationServer.Channel.PrepareResponse(approval);
50                         return response.AsActionResult();
51                     }
52                 }
53             }
54         }
55 
56         public ActionResult Index()
57         {
58             ViewBag.Body = "Welcome To OAuth2.0";
59             return View();
60         }
61     }

這是授權服務端的主要代碼。AuthorizeUrl和userkey分別表示什么意思?

這里涉及到我所在公司的具體情況,簡單地說,用戶授權的具體邏輯是由另外單獨的站點(AuthorizeUrl表示,為方便描述,稱為A站點)引導,所以這里的代碼主要起到一個跳轉的作用。我們看DotNetOpenAuth的官方Demo,會發現授權服務端有登錄頁面、授權頁面等等,其實本質是一樣的,只是拆分成兩個站點。除了OAuth參數,此處可能會傳遞其它參數,所以使用_queryParameters來區分,並分別構建兩部分查詢字符串,OAuth參數會附加到callback地址參數上,用戶授權后會從A站點跳回該地址(此處就是該action所表示的地址),然后返回瀏覽器授權碼。

關於userkey,大家看到有個解密的步驟(第47行),so,這肯定是考慮到安全問題。公司的業務邏輯大多采用userid標示用戶,為自增長int類型,用戶通過A站點授權后通過瀏覽器callback時,userid可以在地址欄中被捕捉到,假如復制該地址並隨意更改userid值,就很有可能在對應用戶未授權的情況下獲得其訪問權限。所以我們不允許直接傳遞userid,而是經過一層對稱加密,這就是userkey的由來。如果授權邏輯並未拆分成獨立站點,那么就不存在這種情況了。

 

后續我可能會再補充若干內容,由於工作較忙,只對有朋友提出疑問的地方做一說明;若有其它問題,請告知,我會不定期更新。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM