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 AddXXXmé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 401emissã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 Firebasee Customdevem 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 AuthenticationSchemespropriedade 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 AuthenticationFailedeventos e usando qualquer coisa que não seja a primeira AddJwtBearerpolítica, verá que IDX10501: Signature validation failed. Unable to match key...isso é causado pelo sistema verificando cada um AddJwtBearerpor vez até obter uma correspondência. O erro geralmente pode ser ignorado.