使用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的由来。如果授权逻辑并未拆分成独立站点,那么就不存在这种情况了。
后续我可能会再补充若干内容,由于工作较忙,只对有朋友提出疑问的地方做一说明;若有其它问题,请告知,我会不定期更新。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
· DeepSeek 解答了困扰我五年的技术问题
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库