Использование промежуточного программного обеспечения аутентификации файлов cookie и промежуточного программного обеспечения аутентификации JWT. Когда я вхожу в систему, я создаю пользовательские претензии и прикрепляю их к идентификатору на основе файлов cookie. Я также получаю токен jwt из внешнего источника, и у него есть свои требования (я использую этот токен для доступа к внешним ресурсам). Мой класс контроллера выглядит примерно так при включении аутентификации
[Authorize(AuthenticationSchemes = AuthSchemes)]
public class MixedController : Controller
// Requires the following imports:
// using Microsoft.AspNetCore.Authentication.Cookies;
// using Microsoft.AspNetCore.Authentication.JwtBearer;
private const string AuthSchemes =
CookieAuthenticationDefaults.AuthenticationScheme + "," +
JwtBearerDefaults.AuthenticationScheme;
На основании приведенного выше фрагмента кода, если аутентификация Cookie или JWT прошла успешно, запрос считается аутентифицированным. Мое требование - отклонить запрос, если аутентификация Cookie или JWT не удалась. Использование только одной схемы не является хорошим вариантом для моего случая. Если мой файл cookie действителен, но срок действия моего токена истек, я бы хотел отклонить запрос на основании «непрохождения аутентификации». Как я могу это сделать?

Используйте аутентификацию на основе политик. Там вы можете проверить, есть ли у текущего ClaimsPrincipal (context.User) 2 Identities, по 1 от каждой успешно пройденной схемы аутентификации. Настроить политику
services.AddAuthorization(options =>
{
options.AddPolicy("RequireAllSchemes", policy =>
{
policy.AddAuthenticationSchemes(CookieAuthenticationDefaults.AuthenticationScheme);
policy.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme);
policy.RequireAuthenticatedUser();
policy.RequireAssertion(context =>
{
return context.User.Identities.Count() == 2;
});
});
});
Укажите политику авторизации для контроллера
[Authorize(Policy = "RequireAllSchemes")]
public class MixedController : Controller
@Jonathan Я обновил (и на этот раз проверил) свой ответ. Пожалуйста, попробуйте.
@Jonathan Также вам необходимо реализовать проверку срока действия для jwt, потому что он может считаться действительным и проходить аутентификацию.
Большое Вам спасибо. Это сработало для меня. Да, у меня есть проверка срока действия. Мне также нравится, как вы инкапсулировали свое решение в политику — это действительно помогает при повторном использовании.
Альтернативный подход
services.AddAuthorization(options => {
options.AddPolicy(Policies.Users, policy => {
policy.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme);
policy.AddAuthenticationSchemes(CookieAuthenticationDefaults.AuthenticationScheme)
policy.RequireAuthenticatedUser();
policy.RequireClaim(JwtClaimTypes.Scope, ResourceNames.IdentityUsers);
policy.RequireClaim(BasicClaimTypes.Admin, bool.TrueString.ToLower());
});});
Спасибо Александр. Я попробовал этот подход. К сожалению, поведение было таким же, как когда я использовал схему, разделенную запятыми. Что меня удивляет, потому что у меня сложилось впечатление, что когда фильтр [Authorize] выходит из строя, он замыкает конвейер фильтра mvc. В моем случае, когда у меня есть недопустимый jwt (истекший) и действительный файл cookie, я все равно получаю доступ к маршруту.