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 OnMessageReceived
Ereignis hinzugefügt . Dadurch kann ich token
den 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 User
Objekt wie benötigt.)
Aber beim ersten Anruf wird der OnMessageReceived
nicht getroffen. Und das User
Objekt in meinem Controller ist nicht eingerichtet.
Ich habe HttpContext
nach diesem ersten Aufruf gesucht und der Header "X-JWT-Assertion" befindet sich in der Request.Headers
Liste (mit dem JWT darin). Aber aus irgendeinem Grund ist die OnMessageReceived
Veranstaltung nicht dafür vorgesehen.
Wie kann ich OnMessageReceived
zum ersten Aufruf eines Servicevorgangs für meinen Service aufgerufen werden?
WICHTIGER HINWEIS: Ich finde heraus , dass das Problem war async
await
in 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 , AddJwtBearer
mit async
await
denen es einen tatsächlichen wartet HttpClient
Anruf. Oder zeigen Sie die Dokumentation, warum async
await
nicht mit verwendet werden soll AddJwtBearer
.
async
await
daran, 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 OnMessageReceived
Lambda möglicherweise asynchron machen, Ihren http-Aufruf in den OnMessageReceived
Body verschieben und dort irgendwie Cache-Ergebnisse erzielen könnten .