(原)NET CORE3.1自定义JWT授权验证

原文链接地址: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());
        }
    }

猜你喜欢

转载自www.cnblogs.com/ruyun/p/12134290.html