Ich verwende WSO2 als meinen Identity Provider (IDP). Es setzt das JWT in einen Header namens "X-JWT-Assertion".
Um dies in das ASP.NET Core-System einzuspeisen, habe ich ein OnMessageReceivedEreignis hinzugefügt . Dadurch kann ich tokenden Wert auf den im Header angegebenen Wert einstellen .
Hier ist der Code, den ich dazu machen muss (der Schlüsselteil sind die letzten 3 Zeilen des Codes ohne Klammern):
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;
}
}
};
Dies alles funktioniert perfekt, bis auf den ersten Anruf nach dem Start des Dienstes. Um klar zu sein, jeder Anruf, bis auf den ersten, funktioniert genau so, wie ich es möchte. (Es legt den Token ein und aktualisiert das UserObjekt wie benötigt.)
Aber beim ersten Anruf wird der OnMessageReceivednicht getroffen. Und das UserObjekt in meinem Controller ist nicht eingerichtet.
Ich habe HttpContextnach diesem ersten Aufruf gesucht und der Header "X-JWT-Assertion" befindet sich in der Request.HeadersListe (mit dem JWT darin). Aber aus irgendeinem Grund ist die OnMessageReceivedVeranstaltung nicht dafür vorgesehen.
Wie kann ich OnMessageReceivedzum ersten Aufruf eines Servicevorgangs für meinen Service aufgerufen werden?
WICHTIGER HINWEIS: Ich finde heraus , dass das Problem war async awaitin AddJwtBearer. (Siehe meine Antwort unten.) Das wollte ich wirklich von dieser Frage.
Da jedoch eine Prämie nicht cancled werden kann, werde ich vergeben noch die Prämie für jeden, der einen Weg zu verwenden , zeigen kann , AddJwtBearermit async awaitdenen es einen tatsächlichen wartet HttpClientAnruf. Oder zeigen Sie die Dokumentation, warum async awaitnicht mit verwendet werden soll AddJwtBearer.
async awaitdaran, dass die
AddJwtBearer(und zugrunde liegende AuthenticationBuilder.AddSchemeHelper) keine asynchronen Aufrufe erwarten - es werden lediglich IConfigureOptions zu Serices hinzugefügt. OnMessageReceived, auf der anderen Seite - wird am erwartet. Ich frage mich also, ob Sie dieses OnMessageReceivedLambda möglicherweise asynchron machen, Ihren http-Aufruf in den OnMessageReceivedBody verschieben und dort irgendwie Cache-Ergebnisse erzielen könnten .