ASP.NET OAuth 2.0 新手上路
OAuth2.0资料
初衷:一直想整理授权系列demo,让自己项目高端大尚,列出新手授权系列,帮助小白程序员不用在为授权头疼
OAuth 允许用户提供一个令牌,而不是用户名和密码来访问他们存放在特定服务提供者的数据。每一个令牌授权一个特定的网站(例如,视频编辑网站)在特定的时段(例如,接下来的 2 小时内)内访问特定的资源(例如仅仅是某一相册中的视频)。这样,OAuth 让用户可以授权第三方网站访问他们存储在另外服务提供者的某些特定信息,而非所有内容。
以上概念来自:https://zh.wikipedia.org/wiki/OAuth
详细理论知识,参考文章如下文章,本文章重在实践
1.http://www.cnblogs.com/lanxiaoke/p/6358332.html
2.https://www.cnblogs.com/selimsong/p/8037717.html
3.http://www.cnblogs.com/xishuai/p/aspnet-webapi-owin-oauth2.html
项目实践开发
步骤1和步骤2都行,看官乐意就行
步骤1
通过NuGet安装
Microsoft.Owin.Security.OAuth
Owin Microsoft.Owin.Host.SystemWeb(重点)
步骤2
Owin Microsoft.Owin.Host.SystemWeb(重点)
Microsoft.Owin.Security.OAuth
Microsoft.Owin.Security.Cookies(可忽略)
Microsoft.AspNet.Identity.Owin
重点在于步骤1少了一个核心dll,少了这个核心dll无法启动部署owin
新增Startup.cs
[assembly: OwinStartup(typeof(OAuth2.Startup))] namespace OAuth2 { public partial class Startup { public void Configuration(IAppBuilder app) { ConfigureAuth(app); } } }
Owin Microsoft.Owin.Host.SystemWeb 通过这个dll,程序启动时候注册,如果不引用,该方法不会生效,看官可以打个断点试一试
新增Startup.Auth.cs
namespace OAuth2 { public partial class Startup { public void ConfigureAuth(IAppBuilder app) { app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions() { //从url中获取token,兼容hearder方式 //Provider = new QueryStringOAuthBearerProvider("access_token") }); var OAuthOptions = new OAuthAuthorizationServerOptions { AllowInsecureHttp = true, TokenEndpointPath = new PathString("/token"), //获取 access_token 认证服务请求地址 AuthorizeEndpointPath = new PathString("/authorize"), //获取 authorization_code 认证服务请求地址 AccessTokenExpireTimeSpan = TimeSpan.FromSeconds(3600), //access_token 过期时间 Provider = new OpenAuthorizationServerProvider(), //access_token 相关认证服务 AuthorizationCodeProvider = new OpenAuthorizationCodeProvider(), //authorization_code 认证服务 RefreshTokenProvider = new OpenRefreshTokenProvider() //refresh_token 认证服务 }; app.UseOAuthBearerTokens(OAuthOptions); //表示 token_type 使用 bearer 方式 } } public class QueryStringOAuthBearerProvider : OAuthBearerAuthenticationProvider { readonly string _name; public QueryStringOAuthBearerProvider(string name) { _name = name; } public override Task RequestToken(OAuthRequestTokenContext context) { var value = context.Request.Query.Get(_name); if (!string.IsNullOrEmpty(value)) { context.Token = value; } return Task.FromResult<object>(null); } } }
眼光犀利的同学肯定注意到这两个类名相同,命名空间也相同,为什么没有报错 请注意关键字 partial
OpenAuthorizationServerProvider示例代码 详细见demo,只提代码需要注意地方
/// <summary> /// 验证 client 信息 /// </summary> public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context) { string clientId; string clientSecret; if (!context.TryGetBasicCredentials(out clientId, out clientSecret)) { context.TryGetFormCredentials(out clientId, out clientSecret); } if (clientId != "xishuai" || clientSecret != "123") { context.SetError("invalid_client", "client or clientSecret is not valid"); return; } context.Validated(); }
public string BaseString() { string clientId = "xishuai"; string clientSecret = "123"; return Convert.ToBase64String(Encoding.ASCII.GetBytes(clientId + ":" + clientSecret)); }
验证生效如图 按照如下格式 key:value,然后base64编码
context.TryGetBasicCredentials 否则解析不了 验证不通过
OpenAuthorizationCodeProvider示例代码 详细见demo
OpenRefreshTokenProvider 示例代码 详细见demo
新增ValueController.cs
public class ValueController : ApiController { // GET api/values access_token验证才能访问 [Authorize] [HttpGet] public IEnumerable<string> Index() { return new string[] { "value1", "value2" }; }
//获取授权code [HttpGet] [Route("api/authorization_code")] public HttpResponseMessage Get(string code) { return new HttpResponseMessage() { Content = new StringContent(code, Encoding.UTF8, "text/plain") }; } }
新增OAuthon2Controller.cs
public class OAuthon2Controller : Controller { //根据你项目端口 private const string HOST_ADDRESS = "http://localhost:60903"; // GET: OAuthon2 直接获取授权code链接,方便获取code public string Index() { string clientId = "xishuai"; string url = $"{HOST_ADDRESS}/authorize?grant_type=authorization_code&response_type=code&client_id={clientId}&redirect_uri={HttpUtility.UrlEncode($"{HOST_ADDRESS}/api/authorization_code")}"; return url; } }
根据获取的url, 在将红色部分url复制出来到浏览器中可以获取到code
现在code有了 将获取access_token
grant_type:authorization_code
code:图上红色url返回给你的
client_id:xishuai 可以理解为appid 自定义,因为代码中固定了,你可以改
redirect_uri:这个链接你也能改的,接受code 在ValueController.cs (action:api/authorization_code)
http://localhost:60903/api/authorization_code
这个地方需要注意 需要和你获取code redirect_uri保持一致就行
string url = $"{HOST_ADDRESS}/authorize?grant_type=authorization_code&response_type=code&client_id={clientId}&redirect_uri={HttpUtility.UrlEncode($"{HOST_ADDRESS}/api/authorization_code")}";
然后你就拿到access_token 去调用 api/Value/Index
如果这个地方你输入错,会获取失败
Authorization Bearer后面空格 在输入access_token