使用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的由來。如果授權邏輯并未拆分成獨立站點,那么就不存在這種情況了。
后續我可能會再補充若干內容,由于工作較忙,只對有朋友提出疑問的地方做一說明;若有其它問題,請告知,我會不定期更新。

浙公網安備 33010602011771號