Você pode alcançar totalmente o que deseja:
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();
});
Vamos examinar as diferenças entre o seu código e aquele.
AddAuthentication
não tem parâmetro
Se você definir um esquema de autenticação padrão, a cada solicitação, o middleware de autenticação tentará executar o manipulador de autenticação associado ao esquema de autenticação padrão. Já que agora temos dois esquemas de autenticação acessíveis, não há sentido em executar um deles.
Use outra sobrecarga de AddJwtBearer
Cada AddXXX
método para adicionar uma autenticação tem várias sobrecargas:
Agora, como você usa o mesmo método de autenticação duas vezes, mas os esquemas de autenticação devem ser exclusivos, você precisa usar a segunda sobrecarga.
Atualize a política padrão
Como as solicitações não serão mais autenticadas automaticamente, colocar [Authorize]
atributos em algumas ações resultará na rejeição das solicitações e na HTTP 401
emissão de um.
Como não queremos isso porque queremos dar aos manipuladores de autenticação a chance de autenticar a solicitação, alteramos a política padrão do sistema de autorização indicando que os esquemas de autenticação Firebase
e Custom
devem ser tentados para autenticar a solicitação.
Isso não o impede de ser mais restritivo em algumas ações; o [Authorize]
atributo tem uma AuthenticationSchemes
propriedade que permite substituir quais esquemas de autenticação são válidos.
Se você tiver cenários mais complexos, pode usar a autorização baseada em políticas . Acho que a documentação oficial é ótima.
Vamos imaginar que algumas ações estão disponíveis apenas para tokens JWT emitidos pelo Firebase e devem ter uma declaração com um valor específico; você poderia fazer desta forma:
services
.AddAuthorization(options =>
{
options.DefaultPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.AddAuthenticationSchemes("Firebase", "Custom")
.Build();
options.AddPolicy("FirebaseAdministrators", new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.AddAuthenticationSchemes("Firebase")
.RequireClaim("role", "admin")
.Build());
});
Você pode então usar [Authorize(Policy = "FirebaseAdministrators")]
em algumas ações.
Um último ponto a ser observado: se você estiver capturando AuthenticationFailed
eventos e usando qualquer coisa que não seja a primeira AddJwtBearer
política, verá que IDX10501: Signature validation failed. Unable to match key...
isso é causado pelo sistema verificando cada um AddJwtBearer
por vez até obter uma correspondência. O erro geralmente pode ser ignorado.