OAuth2 的原理这里不多讲,可以看:https://www.cnblogs.com/icebutterfly/p/8066548.html
直奔主题:这里要实现的功能为,统计微软的Owin程序集实现本地获取token,完成token工作。
上代码:
第一步:配置Startup.Auth.cs
public partial class Startup { public void ConfigureAuth(IAppBuilder app) { app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions { AllowInsecureHttp = true, TokenEndpointPath = new PathString("/oauth2/token"),//设置获取token地址 Provider = new MyOAuthAuthorizationServerProvider(),//自定义token验证 AccessTokenExpireTimeSpan = TimeSpan.FromSeconds(300)//定义token过期时间 }); //下面必须加用bearer方式 app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions() { }); } }
第二步:继承OAuthAuthorizationServerProvider接口,重新里面的严重方法。我只实现通过用户名密码获取token,所以只重写两个方法即可
public class MyOAuthAuthorizationServerProvider : OAuthAuthorizationServerProvider { public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context) { string clientId; string clientSecret; if (!context.TryGetBasicCredentials(out clientId, out clientSecret)) { context.TryGetFormCredentials(out clientId, out clientSecret); } if (context.ClientId == null) { context.SetError("invalid_clientId", "client_Id is not set"); return Task.FromResult<object>(null); } if (!string.IsNullOrEmpty(clientSecret)) { context.OwinContext.Set("clientSecret", clientSecret); } var client = ClientRepository.Clients.Where(c => c.Id == clientId).FirstOrDefault(); if (client != null) { context.Validated(); } else { context.SetError("invalid_clientId", string.Format("Invalid client_id '{0}'", context.ClientId)); return Task.FromResult<object>(null); } return Task.FromResult<object>(null); } public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) { //这里写验证代码 if (context.UserName=="admin"&&context.Password=="123456") { var identity = new ClaimsIdentity( new GenericIdentity(context.UserName, OAuthDefaults.AuthenticationType), context.Scope.Select(x => new Claim("urn:oauth:scope", x))); context.Validated(identity); } else { context.SetError("invalid_grant", "The user name or password is incorrect"); return Task.FromResult<object>(null); } return Task.FromResult(0); } }
第三步:定义Client实体
public class Client { public string Id { get; set; } } public class ClientRepository { public static List<Client> Clients = new List<Client>() { new Client{ Id = "test1" }, new Client{ Id = "test2", } }; }
第四步:编写测试方法
public class HomeController : Controller { [Authorize]//授权标签 public ActionResult Test() { //获取到授权登陆用户 var authentication = HttpContext.GetOwinContext().Authentication; string name= authentication.User.Identity.Name; return Json(new { Message="Hello world",name= name }); } }
OK,就这么简单完成。
现在来测试:
第一步:获取token,我用的POSTMan。成功获取到token
第二步:用postman测试也行,这里贴出用ajax请求的结果
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title></title> <meta charset="utf-8" /> <script src="Scripts/jquery-1.10.2.js"></script> <script> function ajax() { $.ajax({ url: '/home/test', type: 'POST', contentType: 'application/x-www-form-urlencoded', headers: { 'Authorization': 'Bearer ' + $('#token').val(), }, data: {}, success: function (data) { console.log(data); }, }) } </script> </head> <body> <input type="text" id="token" /> <input type="button" value="提交" onclick="ajax()" /> </body> </html>
测试结果为:
{ "Message": "Hello world", "name": "admin" }