基于令牌的认证
我们知道WEB网站的身份验证一般通过session或者cookie完成的,登录成功后客户端发送的任何请求都带上cookie,服务端根据客户端发送来的cookie来识别用户。
WEB API使用这样的方法不是很适合,于是就有了基于令牌的认证,使用令牌认证有几个好处:可扩展性、松散耦合、移动终端调用比较简单等等。
Step 1:安装所需的NuGet包:
Install-Package Microsoft.AspNet.WebApi.Owin -Version 5.1.2 Install-Package Microsoft.Owin.Host.SystemWeb -Version 2.1.0 Install-Package Microsoft.AspNet.Identity.Owin -Version 2.0.1 Install-Package Microsoft.Owin.Cors -Version 2.1.0
Step 2 在项目下添加“Startup.Auth”类
默认会在App_Start文件夹里
using System; using System.Collections.Generic; using System.Linq; using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity.EntityFramework; using Microsoft.Owin; using Microsoft.Owin.Security.Cookies; using Microsoft.Owin.Security.Google; using Microsoft.Owin.Security.OAuth; using Owin; using System.Web.Http; namespace SJOA { public partial class Startup { public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; } public static string PublicClientId { get; private set; } public void Configuration(IAppBuilder app) { HttpConfiguration config = new HttpConfiguration(); ConfigureOAuth(app); WebApiConfig.Register(config); app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); app.UseWebApi(config); } public void ConfigureOAuth(IAppBuilder app) { OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions() { AllowInsecureHttp = true, TokenEndpointPath = new PathString("/token"), AccessTokenExpireTimeSpan = TimeSpan.FromDays(1), Provider = new SimpleAuthorizationServerProvider() }; app.UseOAuthAuthorizationServer(OAuthServerOptions); app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions()); } } }
Step 3:在项目下添加验证类 SimpleAuthorizationServerProvider
using System.Threading.Tasks; using System.Security.Claims; using Microsoft.Owin.Security.OAuth; using Microsoft.Owin.Security; using SJOA.Entity.Models.Tables; using SJOA.Core.BLL; namespace SJOA { /// <summary> /// Token验证 /// </summary> public class SimpleAuthorizationServerProvider : OAuthAuthorizationServerProvider { public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context) { await Task.Factory.StartNew(() => context.Validated()); } public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) { await Task.Factory.StartNew(() => context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" })); try { var userName = context.UserName; var password = context.Password; UserBLL bll = new UserBLL();
//验证用户名,密码 Users user =await Task.Factory.StartNew(() => bll.Query(userName, password)); if (user == null) { context.SetError("invalid_grant", "用户名或密码错误"); return; } else { var oAuthIdentity = new ClaimsIdentity(context.Options.AuthenticationType); oAuthIdentity.AddClaim(new Claim("sub", context.UserName)); oAuthIdentity.AddClaim(new Claim("role", "user")); oAuthIdentity.AddClaim(new Claim(ClaimTypes.Name, user.UserName)); oAuthIdentity.AddClaim(new Claim(ClaimTypes.UserData, user.UserID.ToString())); var authenticationProperties = new AuthenticationProperties(); var ticket = new AuthenticationTicket(oAuthIdentity, authenticationProperties); context.Validated(ticket); } } catch (System.Exception ex) { throw; } } } }
Step 4:让CORS起作用
在ASP.NET Web API中启用OAuth的Access Token验证非常简单,只需在相应的Controller或Action加上[Authorize]标记
Step 5:获取Token
获取token, POST请求本地http://localhost:23477/token
请求头 Content-Type:application/x-www-form-urlencoded
参数BODY格式:
grant_type=password
username=admin
password=123456
token请求到以后,可以缓存在客户端,然后客户端再拿着token请求其它接口
Step 6:请求接口
只要在http请求头中加上Authorization:bearer Token就可以成功请求接口了
GET http://localhost:49209/api/sys/Dept/GetALLDept
Authorization : bearer T5jF97t5n-rBkWcwpiVDAlhzXtOvV7Jw2NnN1Aldc--xtDrvWtqLAN9hxJN3Fy7piIqNWeLMNm2IKVOqmmC0X5_s8MwQ6zufUDbvF4Bg5OHoHTKHX6NmZGNrU4mjpCuPLtSbT5bh_gFOZHoIXXIKmqD3Wu1MyyKKNhj9XPEIkd9bl4E9AZ1wAt4dyUxmPVA_VKuN7UvYJ97TkO04XyGqmXGtfVWKfM75mNVYNhySWTg
至此,项目的Token验证就完成了