本文发布于1016 天前,其中的信息可能已经过时,如有错误请发送邮件到Sunshineforluck@163.com
1.创建生成一个新的JWT在登入时
/// <summary>
/// 登入时生成Token
/// </summary>
/// <param name="yuanUser">用户实体</param>
/// <returns></returns>
public async Task<Result> CreateJWT(int id)
{
//选择签名算法
var signingAlogorithm = SecurityAlgorithms.HmacSha256;
//获取该用户的权限列表
var permissionInfo = await _repository.GetListAsync(x => x.Id == id);
//准备存放用户信息的 Claim 数组
var claims = new List<Claim>{
//new Claim(JwtRegisteredClaimNames.Sub, demoEntityUser.Password)
};
//如果该用户有权限,则依次加入到 claims 数组中
var permissionClaims = permissionInfo.Select(p => new Claim("permission", p.DepartmentId.ToString()));
claims.AddRange(permissionClaims);
//如果该用户没有任何权限,则加入 "NoPermission" 权限
if (!permissionClaims.Any())
{
claims.Add(new Claim("permission", "NoPermission"));
}
//生成私钥
var secretByte = Encoding.UTF8.GetBytes(_configuration["Authentication:SecretKey"]);
var signingKey = new SymmetricSecurityKey(secretByte);
//生成数字签名
var signingCredentials = new SigningCredentials(signingKey, signingAlogorithm);
//生成 JWT 并返回
var token = new JwtSecurityToken(
issuer: _configuration["Authentication:Issuer"],
audience: _configuration["Authentication:Audience"],
claims: claims,
notBefore: DateTime.UtcNow,
expires: DateTime.UtcNow.AddYears(1),
signingCredentials: signingCredentials);
var tokenString = new JwtSecurityTokenHandler().WriteToken(token);
return Result.Success(tokenString);
}
2.创建一个验证用的类
public class MyAuthorizeFilter : ActionFilterAttribute
{
public string Permission { get; set; }
//private static readonly string _missingAuthorizationMessage = "Authorization缺失";
private static readonly string _missingTokenMessage = "token缺失";
private static readonly string _invalidTokenMessage = "token无效";
private static readonly string _expiredTokenMessage = "token过期";
private static readonly string _noPermissionMessage = "该用户没有当前权限";
private static readonly string _networkErrorMessage = "网络错误";
public override void OnActionExecuting(ActionExecutingContext context)
{
try
{
var token = context.HttpContext.Request.Headers["Authorization"].ToString();
if (string.IsNullOrEmpty(token))
{
context.Result = new JsonResult(new Result(403, _missingTokenMessage, "No Data"));
return;
}
var secretKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes("21232F297A57A5A743894A0E4A801FC3"));
var validationParameters = new TokenValidationParameters()
{
ValidateAudience = true,
ValidAudience = "Abp_samples",
ValidateIssuer = true,
ValidIssuer = "Abp_samples",
ValidateLifetime = true,
IssuerSigningKey = secretKey,
ValidateIssuerSigningKey = true
};
var handler = new JwtSecurityTokenHandler();
var principal = handler.ValidateToken(token, validationParameters, out var validatedToken);
var claims = principal.Claims;
if (claims != null)
{
var isAuthorized = false;
foreach (var claim in claims)
{
if (claim.Type.Equals("permission", StringComparison.InvariantCultureIgnoreCase) && claim.Value.Equals(Permission, StringComparison.InvariantCultureIgnoreCase))
{
isAuthorized = true;
break;
}
//if (claim)
//{
// isAuthorized = true;
// break;
//}
}
if (!isAuthorized)
{
//没有权限
context.Result = new JsonResult(new Result(401, _noPermissionMessage, "No Data"));
return;
}
}
else
{
//丢失令牌信息
context.Result = new JsonResult(new Result(403, _missingTokenMessage, "No Data"));
return;
}
}
catch (SecurityTokenExpiredException)
{
//令牌过期
context.Result = new JsonResult(new Result(403, _expiredTokenMessage, "No Data"));
return;
}
catch (SecurityTokenException)
{
//无效的令牌
context.Result = new JsonResult(new Result(403, _invalidTokenMessage, "No Data"));
return;
}
catch (Exception)
{
//网络错误
context.Result = new JsonResult(new Result(500, _networkErrorMessage, "No Data"));
return;
}
}
}
3.在调用接口的时候添加签名
/// <summary>
/// 分页获取demo列表
/// </summary>
/// <param name="selectDto">Dto</param>
/// <returns></returns>
[HttpPost("GetPagingDemoEntityUser"),MyAuthorizeFilter(Permission="1")]
public async Task<Result> GetPagingDemoEntityUser([FromQuery] SelectDemoEntityUserDto selectDto)
{
return await _demoEntityUserAppService.GetPagingDemoEntityUser(selectDto);
}
需要注意,此处Permission="1"
为能够访问到该API的用户权限名称,你可以在你的数据库中自定义,并且在生成JWT的时候将信息添加到JWT中。