У меня есть несколько конечных точек API (.net core mvc), которые будут использовать зарегистрированного пользователя (JWT), если пользователь вошел в систему, но любой может вызывать метод.Используя [AllowAnonymous]
вместе с [Authorize]
, я получаю нужную функциональность, но если срок действия отправленного JWT истек, я не получаю 401, а вместо этого он обрабатывается как анонимный запрос.
Мне нужна логика авторизации для обработки конечной точки, как это было [Authorize]
, только если есть заголовок Authorization: Bearer, означающий, что если токен истек, он должен вернуть 401
Эта функциональность необходима толькона нескольких конечных точках, а не на полном контроллере
Я попробовал комбинацию [AllowAnonymous]
+ [Authorize]
.
Также пытался RequireAssertion
при создании политики, но, похоже, для этого
Метод, который я использую для тестирования:
[HttpPost]
[Route("testToken")]
[AllowAnonymous]
[Authorize(Policy = AuthFilterConvension.POLICY_AUTHORIZE_WHEN_HAS_BEARER)]
public async Task<IActionResult> testToken()
{
var user = await _signInManager.UserManager.GetUserAsync(HttpContext.User);
return Ok(new {result = user});
}
Настройка аутентификации для поддержки обоих файлов cookie + jwt:
services.AddAuthorization(o =>
{
o.AddPolicy(AuthFilterConvension.POLICY_AUTHORIZE_WHEN_HAS_BEARER, b =>
{
b.RequireRole("Admin");
b.RequireAuthenticatedUser();
b.AuthenticationSchemes = new List<string> {JwtBearerDefaults.AuthenticationScheme};
});
});
services.AddAuthentication()
.AddCookie()
.AddJwtBearer(cfg =>
{
var issuer = Environment.GetEnvironmentVariable("JWT_ISSUER");
var tokenKey = Environment.GetEnvironmentVariable("JWT_TOKEN_KEY");
cfg.RequireHttpsMetadata = false;
cfg.SaveToken = true;
cfg.TokenValidationParameters = new TokenValidationParameters
{
RequireExpirationTime = true,
RequireSignedTokens = true,
ValidateAudience = true,
ValidateIssuer = true,
ValidateLifetime = true,
ValidIssuer = issuer,
ValidAudience = issuer,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(tokenKey))
};
}
);
Я ожидаю, что заголовок [Authorize]
вернет 401 Не авторизовано при использовании токенов с истекшим сроком вместо вызова метода как анонимного.Можно ли это настроить?
Обновление Я создал атрибут следующим образом:
public class AuthorizeBearerWhenPresent : ActionFilterAttribute, IAsyncAuthorizationFilter
{
public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
{
var headers = context.HttpContext.Request;
//TODO: Test header
var httpContext = context.HttpContext;
var authService = httpContext.RequestServices.GetRequiredService<IAuthorizationService>();
var authResult = await authService.AuthorizeAsync(httpContext.User, context,
AuthFilterConvension.POLICY_AUTHORIZE_WHEN_HAS_BEARER);
if (!authResult.Succeeded)
{
context.Result = new UnauthorizedResult();
}
}
}
Однако, независимо от того, что я отправляю на authService
этовозвращает истину.Не имеет значения, отправляю ли я неверный заголовок JWT или нет.Разве это не должен быть правильный способ выполнения политики?