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