Authorization其目标就是验证Http请求能否通过验证。ASP.Net Core提供了很多种Authorization方式,详细可以参考 微软官方文档。在这里只详细介绍三种方式:
Policy
Middleware
Custom Attribute
一、Role授权
代码如下:
#region jwt验证 services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidIssuer = Configuration["Jwt:Issuer"], ValidAudience = Configuration["Jwt:Audience"], IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:SecretKey"])) }; }); #endregion
在Claim中设置了Role
所以我们可以将 [Authorize] 标签写成[Authorize(Roles="admin")]
只有解析出来的token中的角色为admin才授权成功,才可以进入方法内,
在new Claim(ClaimTypes.Role, user) //包含类型为Role的Claim。
如果变量名user是Admin通过[Authorize(Roles="admin")]则验证不通过,小写的admin则通过,(区分大小写)
二、Claims授权
1、要使用Claims授权,我们首先需要在Startup.cs的ConfigureServices方法中添加授权
授权代码:
#region jwt验证 services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidIssuer = Configuration["Jwt:Issuer"], ValidAudience = Configuration["Jwt:Audience"], IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:SecretKey"])) }; }); #endregion #region 授权 services.AddAuthorization(options => { options.AddPolicy("EmployeeOnly", policy => { policy.RequireClaim("EmployeeNumber"); }); }); //如上,我们定义了一个名称为EmployeeOnly的授权策略,它要求用户的Claims中必须包含类型为EmployeeNumber的Claim。 #endregion
然后在CommonController.cs生成token的action中的Claim中添加EmployeeNumber
最后在需要权限认证的地方使用标签 [Authorize(Policy="EmployeeOnly")]
我们首先获取一下token,到jwt官网上解析一下发现token中包含EmployeeNumber
然后访问成功
如果Claim不包含EmployeeNumber类型的,则访问失败。
访问
三、自己定制JWT验证(自定义Token获取方式)
自定义类似jwt的token验证,也就是说直接从header中拿取我们想要的token
1、Startup.cs中的ConfigureServices方法中注释掉以下内容,然后自定义jwt token
代码如下:
#region jwt验证 services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { /*options.TokenValidationParameters = new TokenValidationParameters { ValidIssuer = Configuration["Jwt:Issuer"], ValidAudience = Configuration["Jwt:Audience"], IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:SecretKey"])) };*/ #region 自定义Jwt的token验证 options.SecurityTokenValidators.Clear();//将SecurityTokenValidators清除掉,否则它会在里面拿验证 options.SecurityTokenValidators.Add(new MyTokenValidator()); //自定义的MyTokenValidator验证方法 options.Events = new JwtBearerEvents { //重写OnMessageReceived OnMessageReceived = context => { var token = context.Request.Headers["mytoken"]; context.Token = token.FirstOrDefault(); return Task.CompletedTask; } }; #endregion }); #endregion
2、接下来我们新建MyTokenValidator.cs类来验证token,并让这个类实现ISecurityTokenValidator接口
代码如下:
using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.IdentityModel.Tokens; using System; using System.Collections.Generic; using System.Linq; using System.Security.Claims; using System.Threading.Tasks; namespace ZanLveCore { public class MyTokenValidator : ISecurityTokenValidator { bool ISecurityTokenValidator.CanValidateToken => true; int ISecurityTokenValidator.MaximumTokenSizeInBytes { get; set; } bool ISecurityTokenValidator.CanReadToken(string securityToken) { return true; } //验证token ClaimsPrincipal ISecurityTokenValidator.ValidateToken(string securityToken, TokenValidationParameters validationParameters, out SecurityToken validatedToken) { validatedToken = null; //判断token是否正确 if (securityToken != "abcdefg") return null; //给Identity赋值 var identity = new ClaimsIdentity(JwtBearerDefaults.AuthenticationScheme); identity.AddClaim(new Claim("name", "wyt")); identity.AddClaim(new Claim(ClaimsIdentity.DefaultRoleClaimType, "admin")); var principle = new ClaimsPrincipal(identity); return principle; } } }
访问成功
Swagger UI访问
其实这种验证方式是 简称 清除验证规则,自定义验证方式
options.SecurityTokenValidators.Clear();//将SecurityTokenValidators清除掉,否则它会在里面拿验证 options.SecurityTokenValidators.Add(new MyTokenValidator()); //自定义的MyTokenValidator验证方法
还有一种方式是 简称 重写验证方式
权限授权Handler的继承AuthorizationHandler的自定义授权类