Für mich war ich migriert und alt, arbeitete aber mit der .NET 4.6.1 MVC-Website auf Core 1.1. Die Arbeit wurde gestoppt, bevor ich sie zum Laufen bringen konnte. Als ich sie wieder aufnahm, migrierte ich zu 2.x.
Mein Problem war, dass der Rückruf von Google mit einem 404
von meiner Website beantwortet wurde . Ich dachte, es sollte schlagen, AccountController.ExternalLoginCallback
also fügte ich ein hinzu [Route(...)]
und sicher traf Googles Rückruf die Aktion.
Dies traf dann die null
in dieser Zeile zurückgegebenen (welche Art von Verrückten gibt a zurück null
?)
var externalLoginInfo = await this.SignInManager.GetExternalLoginInfoAsync();
Ich habe es rückentwickelt, um unter der Haube herauszufinden, dass es letztendlich den Handler bekommt, für ExternalScheme
den für mich der Cookie-Handler war!
Es schien alles falsch zu sein und ich hatte irgendwie das Gefühl, dass die Middleware nur die Rückruf-URI abfangen sollte, also entfernte ich meine [Route(...)]
und das 404
Problem kam zurück.
Ich habe dann festgestellt, dass ich dies beim Start hinzufügen muss.
applicationBuilder.UseAuthentication();
Dies löst das 404
, gibt aber ein anderes Problem.
Es wurde kein authenticationScheme angegeben und es wurde kein DefaultSignInScheme gefunden.
Indem ich hier ein Standardschema hinzufüge, behebe ich den obigen Fehler.
serviceCollection.AddAuthentication(IdentityConstants.ExternalScheme)
.AddGoogle(googleOptions => Configuration.Bind("OAuth2:Providers:Google", googleOptions))
.AddExternalCookie();
Jetzt AccountController.ExternalLoginCallback
wird durch etwas Magie wieder aufgerufen, aber ich bin zurück zum null
Rückgabewert.
Ich habe diesen Code über der betreffenden Zeile hinzugefügt, was im Wesentlichen unter der Haube geschieht (siehe Microsoft-Code auf GitHub). Interessanterweise h
ist es vom Typ CookieAuthenticationHandler
und a
enthält alle meine Ansprüche und Informationen von Google!
var authHandler = this.HttpContext.RequestServices.GetRequiredService<IAuthenticationHandlerProvider>();
var h = await authHandler.GetHandlerAsync(this.HttpContext, IdentityConstants.ExternalScheme);
var a = await h.AuthenticateAsync();
var externalLoginInfo = await this.SignInManager.GetExternalLoginInfoAsync();
Wenn ich in GitHub stöbere und internen Code kopiere, der in meinen Controller läuft, kann ich sehen, dass er ClaimTypes.NameIdentifier
in meinen Ansprüchen nicht gefunden wirdProviderKey
später verwendet.
Hmm ....
Besorgt habe ich alte 1.x verwendet AccountController
Code mit neueren 2.x-Identitätsbits verwendet habe, habe ich einige Beispiele gefunden, die dieses Zeug noch verwenden, und einige Beispiele, die auch Razor Pages für alles verwenden. Ich werde mit dem weitermachen, was ich habe.
Daher werde ich als Nächstes untersuchen, wie zusätzliche JSON-Nutzdaten von Google-Nutzern den Ansprüchen zugeordnet werden. Ich denke, wenn meine Google-Konto-ID (numerisch, denke ich) zugeordnet wäre, würde alles funktionieren.
https://docs.microsoft.com/en-us/aspnet/core/security/authentication/social/additional-claims?view=aspnetcore-2.2
Final Fix
Ich habe das Problem schließlich behoben, indem ich eine "Anspruchsaktion" hinzugefügt habe, um meine Google-Kennung aus dem von Google zurückgegebenen JSON zu entfernen!
serviceCollection.AddAuthentication(IdentityConstants.ExternalScheme)
.AddGoogle(googleOptions =>
{
Configuration.Bind("OAuth2:Providers:Google", googleOptions);
googleOptions.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "sub", "string");
})
.AddExternalCookie();
Das sub
Feld enthält, was schließlich im nameidentifier
Anspruch und dann in dem endet, was ProviderKey
der AccountController
will.