Estou usando o WSO2 como meu provedor de identidade (IDP). Ele está colocando o JWT em um cabeçalho chamado "X-JWT-Assertion".
Para alimentar isso no sistema ASP.NET Core, adicionei um OnMessageReceivedevento. Isso permite que eu defina tokeno valor fornecido no cabeçalho.
Aqui está o código que eu tenho que fazer isso (a parte principal são as últimas 3 linhas do código que não está entre colchetes):
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie()
.AddJwtBearer(async options =>
{
options.TokenValidationParameters =
await wso2Actions.JwtOperations.GetTokenValidationParameters();
options.Events = new JwtBearerEvents()
{
// WSO2 sends the JWT in a different field than what is expected.
// This allows us to feed it in.
OnMessageReceived = context =>
{
context.Token = context.HttpContext.Request.Headers["X-JWT-Assertion"];
return Task.CompletedTask;
}
}
};
Tudo isso funciona perfeitamente, exceto na primeira chamada após o início do serviço. Para ser claro, todas as chamadas, exceto a primeira, funcionam exatamente como eu quero. (Ele coloca o token e atualiza o Userobjeto como eu preciso.)
Mas para a primeira chamada, o OnMessageReceivednão é atingido. E o Userobjeto no meu controlador não está configurado.
Eu verifiquei HttpContexta primeira chamada e o cabeçalho "X-JWT-Assertion" está na Request.Headerslista (com o JWT). Mas, por alguma razão, o OnMessageReceivedevento não é necessário.
Como posso OnMessageReceivedser chamado para a primeira chamada de uma operação de serviço para o meu serviço?
NOTA IMPORTANTE: eu descobri que o problema era async awaitno AddJwtBearer. (Veja minha resposta abaixo.) Era isso que eu realmente queria fora desta questão.
No entanto, como uma recompensa não pode ser excluída, ainda a concederei a qualquer pessoa que possa mostrar uma maneira de usá AddJwtBearer- async awaitla onde está aguardando uma HttpClientligação real . Ou mostre a documentação do motivo pelo qual async awaitnão deve ser usado AddJwtBearer.
async awaitnão funcionar bem com o pipeline de chamadas.)
AddJwtBearer(e subjacente AuthenticationBuilder.AddSchemeHelper) não esperam chamadas assíncronas por lá - apenas adiciona IConfigureOptions aos serviços. OnMessageReceived, por outro lado - está sendo aguardado em. Então, eu estou querendo saber se você poderia fazer esse OnMessageReceivedlambda assíncrono, mover sua chamada http para o OnMessageReceivedcorpo e, de alguma forma, armazenar os resultados lá?