У меня есть простое приложение (API), которое использует аутентификацию JWT.Я реализовал способ проверить, действителен ли токен, основываясь на некоторой информации в БД.Это выглядит примерно так ->
//Check if the token is valid
var tokenStamp = int.Parse(claimsIdentity.FindFirst(JwtRegisteredClaimNames.Iat)?.Value);
if (userDto.PasswordChangedAt > tokenStamp)
{
ModelState.AddModelError("SessionExpired", "Please relog.");
return BadRequest(ModelState);
}
//Done checking token
Я часами пытался перевести этот код в политику, чтобы вместо того, чтобы писать все, что у меня могло бы быть что-то вроде
[Authorize(Policy="MYPOLICY")]
Моя проблема здесь в том, что мне нужно получить информацию из базы данных SQL (как указано выше), чтобы выполнить проверку, и почти все, что я искал в Интернете, было просто «проверкой возраста» со статическими данными.
Я пробовал кое-что, но я, вероятно, только что сделал беспорядок (все еще немного нового для netcore).Здесь ничего не идет ->
public class TokenValidationAuthorizeAttribute : IAuthorizationRequirement
{
public void TokenChangeValidation(AuthorizationHandlerContext context, UserService userService)
{
//var claimsIdentity = this.User.Identity as ClaimsIdentity;
var tokenCreationDate = int.Parse(context.User.FindFirst(c => c.Type == JwtRegisteredClaimNames.Iat).Value);
var userId = int.Parse(context.User.FindFirst(c => c.Type == ClaimTypes.Name).Value);
var user = userService.GetById(userId, false);
var userInfo = Mapper.Map<UserDto>(user);
var tokenStamp = int.Parse(context.User.FindFirst(JwtRegisteredClaimNames.Iat)?.Value);
TokenIssuedAt = tokenStamp;
}
public int TokenIssuedAt { get; set; }
internal IAuthorizationRequirement TokenChangeValidation(AuthorizationHandlerContext context)
{
throw new NotImplementedException();
}
}
public class TokenValidationHandler : AuthorizationHandler<TokenValidationAuthorizeAttribute>
{
const string POLICY_PREFIX = "TokenValidation";
private IUserService _userService;
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,TokenValidationAuthorizeAttribute requirement)
{
var userService = _userService;
//var claimsIdentity = this.User.Identity as ClaimsIdentity;
var tokenCreationDate = int.Parse(context.User.FindFirst(c => c.Type == JwtRegisteredClaimNames.Iat).Value);
var userId = int.Parse(context.User.FindFirst(c => c.Type == ClaimTypes.Name).Value);
var user = userService.GetById(userId, false);
var userInfo = Mapper.Map<UserDto>(user);
var tokenStamp = int.Parse(context.User.FindFirst(JwtRegisteredClaimNames.Iat)?.Value);
if (userInfo.PasswordChangedAt >= requirement.TokenIssuedAt)
{
context.Succeed(requirement);
}
return Task.CompletedTask;
}
}
Но я никоим образом не могу создать новый экземпляр TokenValidationAuthorizeAttribute, так как не могу передать контекст из ConfigureServices, поэтому следующий фрагмент кода, безусловно, не работает.
services.AddAuthorization(options =>
{
options.AddPolicy("TokenOk", policy => policy.Requirements.Add(new TokenValidationAuthorizeAttribute()));
});
Любой совет, чтобы подтолкнуть меня в правильном направлении?