(原)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());
}
}

posted @ 2020-01-16 15:31  大王快跑丶  阅读(2510)  评论(2)    收藏  举报