Вы можете полностью достичь того, чего хотите:
services
.AddAuthentication()
.AddJwtBearer("Firebase", options =>
{
options.Authority = "https://securetoken.google.com/my-firebase-project"
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidIssuer = "my-firebase-project"
ValidateAudience = true,
ValidAudience = "my-firebase-project"
ValidateLifetime = true
};
})
.AddJwtBearer("Custom", options =>
{
});
services
.AddAuthorization(options =>
{
options.DefaultPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.AddAuthenticationSchemes("Firebase", "Custom")
.Build();
});
Давайте рассмотрим различия между вашим кодом и этим.
AddAuthentication
не имеет параметра
Если вы установите схему проверки подлинности по умолчанию, то при каждом отдельном запросе промежуточное ПО проверки подлинности будет пытаться запустить обработчик проверки подлинности, связанный со схемой проверки подлинности по умолчанию. Поскольку теперь у нас есть две возможные схемы аутентификации, запускать одну из них нет смысла.
Используйте другую перегрузку AddJwtBearer
Каждый AddXXX
метод добавления аутентификации имеет несколько перегрузок:
Теперь, поскольку вы используете один и тот же метод аутентификации дважды, но схемы аутентификации должны быть уникальными, вам необходимо использовать вторую перегрузку.
Обновите политику по умолчанию
Поскольку запросы больше не будут аутентифицироваться автоматически, добавление [Authorize]
атрибутов к некоторым действиям приведет к тому, что запросы будут отклонены и HTTP 401
будет выдан.
Так что это не то , что мы хотим , потому что мы хотим , чтобы обработчики проверки подлинности возможности аутентификации запроса, мы изменим политику по умолчанию системы авторизации, указав оба Firebase
и Custom
аутентификацию схемы должно быть пытался проверить подлинность запроса.
Это не мешает вам более ограничивать некоторые действия; у [Authorize]
атрибута есть AuthenticationSchemes
свойство, позволяющее переопределить допустимые схемы аутентификации.
Если у вас есть более сложные сценарии, вы можете использовать авторизацию на основе политик . Я считаю, что официальная документация прекрасна.
Представим, что некоторые действия доступны только для токенов JWT, выпущенных Firebase, и должны иметь заявку с определенным значением; вы можете сделать это так:
services
.AddAuthorization(options =>
{
options.DefaultPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.AddAuthenticationSchemes("Firebase", "Custom")
.Build();
options.AddPolicy("FirebaseAdministrators", new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.AddAuthenticationSchemes("Firebase")
.RequireClaim("role", "admin")
.Build());
});
Затем вы можете использовать [Authorize(Policy = "FirebaseAdministrators")]
для некоторых действий.
И последнее, на что следует обратить внимание: если вы перехватываете AuthenticationFailed
события и используете что-либо, кроме первой AddJwtBearer
политики, вы можете увидеть, IDX10501: Signature validation failed. Unable to match key...
что это вызвано тем, что система проверяет каждое AddJwtBearer
по очереди, пока не найдет совпадение. Ошибка обычно игнорируется.