原文链接地址:https://www.cnblogs.com/ruyun/p/12134290.html
登录获取JWT
[ApiController] public class LoginController : ControllerBase { private readonly IOptions<JwtOption> options;
public LoginController(IOptions<JwtOption> options) { this.options = options; } [HttpGet("/login")] [AllowAnonymous] public IActionResult Login([FromQuery]string username) { string roleType = username == "admin" ? "Administrator" : "Other"; var claims = new Claim[] { new Claim("Role",roleType), }; var token = new JwtToken(options.Value).GenerateToken(claims); return Ok(token); } }
在初始控制器WeatherForecastController中Get上添加[Authorize]
自定义token的生成帮助类
public class JwtToken { private readonly byte[] secret; private readonly string audience; private readonly string issuer; private readonly int expiresMinute;
public JwtToken(JwtOption options) { secret = Encoding.ASCII.GetBytes(options.Secret); audience = options.Audience; issuer = options.Issuer; expiresMinute = options.ExpirationMinutes; } ///生成JWT public JwtResult GenerateToken(Claim[] claims) { var authTime = DateTime.UtcNow; var expiresAt = authTime.AddMinutes(expiresMinute); var tokenDescriptor = new SecurityTokenDescriptor { Audience = audience, Issuer = issuer, Subject = new ClaimsIdentity(claims), Expires = expiresAt, SigningCredentials = new SigningCredentials( new SymmetricSecurityKey(secret), SecurityAlgorithms.HmacSha256Signature) }; var tokenHandler = new JwtSecurityTokenHandler(); var token = tokenHandler.CreateToken(tokenDescriptor); var tokenString = tokenHandler.WriteToken(token); return new JwtResult { access_token = tokenString, token_type = "Bearer", auth_time = new DateTimeOffset(authTime).ToUnixTimeSeconds(), expires_at = new DateTimeOffset(expiresAt).ToUnixTimeSeconds() }; } } public class JwtResult { /// <summary> /// access token /// </summary> public string access_token { get; set; } /// <summary> /// token type /// </summary> public string token_type { get; set; } /// <summary> /// 授权时间 /// </summary> public long auth_time { get; set; } /// <summary> /// 过期时间 /// </summary> public long expires_at { get; set; } } public class JwtOption { public string Secret { get; set; } public string Issuer { get; set; } public string Audience { get; set; } public int ExpirationMinutes { get; set; } }
在Appsettings中添加
"Authorization": {
"Secret": "qtiOLpT7mJQx239e2kgMheAH7B9lGQJnoxYRCb7KX3x1ogDEd55I7dJ1ziYptiTF",
"Issuer": "https://www.cnblogs.com/ruyun/",
"Audience": "https://www.cnblogs.com/ruyun/",
"ExpirationMinutes": "2000"
}
自定义授权类
public class PermissionRequirement : IAuthorizationRequirement { public string PermissionName { get; }
public PermissionRequirement(string PermissionName) { this.PermissionName = PermissionName; } } public class PermissionRequirementHandler : AuthorizationHandler<PermissionRequirement> { private readonly IHttpContextAccessor httpContextAccessor; public PermissionRequirementHandler(IHttpContextAccessor httpContextAccessor) { this.httpContextAccessor = httpContextAccessor; } protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement) { var result = await httpContextAccessor.HttpContext.AuthenticateAsync(JwtBearerDefaults.AuthenticationScheme); if (!result.Succeeded) { context.Fail(); return; } httpContextAccessor.HttpContext.User = result.Principal; var role = httpContextAccessor.HttpContext.User.FindFirst(c => c.Type == "Role"); if (role != null) { var roleValue = role.Value; var permissions = RolePermissionCache.GetPermissions(role.Value); if (permissions.Contains(requirement.PermissionName)) { context.Succeed(requirement); } } return; } } //权限动态缓存类 临时替代数据库 public class RolePermissionCache { //实际在数据库获取与配置 public static List<string> GetPermissions(string role) { switch (role) { case "Administrator": return new List<string>() { "Index", "CustomPermission" }; case "Custom": return new List<string>() { "Index" }; } return new List<string>(); } } internal class PermissionPolicyProvider : IAuthorizationPolicyProvider { //这里默认使用自定义的授权模式 public Task<AuthorizationPolicy> GetDefaultPolicyAsync() { var policy = new AuthorizationPolicyBuilder(); policy.AddRequirements(new PermissionRequirement("CustomPermission")); return Task.FromResult(policy.Build()); } public Task<AuthorizationPolicy> GetFallbackPolicyAsync() { return Task.FromResult(new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build()); } public Task<AuthorizationPolicy> GetPolicyAsync(string policyName) { var policy = new AuthorizationPolicyBuilder(); policy.AddRequirements(new PermissionRequirement(policyName)); return Task.FromResult(policy.Build()); } }