Ви можете повністю досягти того, що хочете:
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по черзі, поки не отримає збіг. Зазвичай помилку можна ігнорувати.