wake-up-neo.net

GetExternalLoginInfoAsync von OWIN Gibt immer null zurück

Ich habe eine neue MVC5-Webanwendung erstellt. Wenn ich versuche, mich bei Google oder Facebook anzumelden, wird die ExternalLoginCallback-Aktion in der AccountController aufgerufen, aber GetExternalLoginInfoAsync() gibt immer null zurück:

var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
if (loginInfo == null)
{
    return RedirectToAction("Login");
}

Da es immer null ist, wird es einfach zurück zur Anmeldeseite geleitet und der Vorgang beginnt von vorne. Wie kann ich das beheben?

63
VineetYadav

Damit die OWIN-Anmeldung bei Google auf einer ASP.Net MVC5-Standardsite von Visual Studio 2013 ordnungsgemäß funktioniert, musste ich:

  1. Richten Sie ein Google OpenId-Konto unter https://console.developers.google.com/project ein

  2. Stellen Sie dort die Rückruf-URL auf blah/signin-google ein.
    Wichtige Hinweise zu Dingen, die Sie nicht tun müssen :

    • Sie müssen nicht HTTPS für Google verwenden, um zurückzuleiten. Sie können sogar zurück zu plain umleiten http: // localhost , kein Problem.

    • Sie müssen für die Weiterleitungs-URL nichts einrichten - keine Routen, Controller-Aktionen oder speziellen Berechtigungen in Web.Config. Die Weiterleitungs-URL lautet immer/signin-google und OWIN erledigt dies für Sie hinter den Kulissen.

Wenn Ihre Website beispielsweise "me.com" lautet, enthält die Google Developer Console möglicherweise die folgenden 3 Rückruf-URLs:

http://localhost:53859/signin-google
http://test.me.com/signin-google
https://me.com/signin-google

Die erste einschließlich der Portnummer, die VS für Ihr Projekt angegeben hat.

  1. Aktivieren Sie die Google+ API . Dies ist ein versteckter Fehler in einem GOTCHA und die Hauptursache für das Problem in der hier gestellten Frage. Wenn Sie dies nicht tun, können Sie leicht übersehen, dass die Anforderung von /account/ExternalLoginCallback&error=access_denied enthält, und das liegt daran, dass Google dies gesagt hat Nein zu einer Berechtigungsanfrage, die OWIN für das Google+ Basisprofil des Nutzers gestellt hat. Ich kann nicht sagen, an wem Google oder Microsoft schuld sind.

Um die Google+ API in der Entwicklerkonsole zu aktivieren, klicken Sie links auf APIs, suchen Sie nach Google+, klicken Sie darauf und klicken Sie auf Aktivieren. Ja, das müssen Sie wirklich tun. Wenn du das nicht tust, bist du abgesprungen.

  1. Fügen Sie die ClientId und ClientSecret hinzu, die Sie von Google in der Entwicklerkonsole zu Startup.Auth hinzugefügt haben. Verbessern Sie jedoch den Code, um OAuth2 explizit zu verwenden, und fragen Sie explizit nach der E-Mail-Adresse des Benutzers:

    var google = new GoogleOAuth2AuthenticationOptions()
    {
        ClientId = "123abc.apps.googleusercontent.com",
        ClientSecret = "456xyz",
        Provider = new GoogleOAuth2AuthenticationProvider()
    };
    google.Scope.Add("email");
    app.UseGoogleAuthentication(google);
    

Das ist es. Damit hat es endlich funktioniert.

Ich möchte es nur noch einmal wiederholen, es gibt viele Antworten zu diesem Thema und zu Problemen, bei denen OWIN/Google nicht funktioniert, und fast alle davon sind für die aktuelle VS2013/MVC5/OWIN-Vorlage falsch.
Sie müssen Web.Config überhaupt nicht ändern.
Sie müssen keinerlei spezielle Routen erstellen.
Sie sollten nicht versuchen, /signin-google auf eine andere Stelle zu verweisen oder eine andere Rückruf-URL zu verwenden, und Sie sollten auf keinen Fall versuchen, sie direkt mit /account/externallogincallback oder externalloginconfirmation zu verknüpfen, da beide voneinander getrennt sind von /signin-google und den erforderlichen Schritten im OWIN/Google-Prozess.

101
Chris Moschini

OK, ich habe herausgefunden, warum es null ist. Sie müssen Google + API in der Google-Konsole aktivieren. Stellen Sie außerdem sicher, dass der geheime Schlüssel nach dem Einfügen in den Code nicht mit einem Leerzeichen am Ende verkettet ist. Warum können sie keine normalen Fehler zurückgeben? Ich weiß es nicht.

45
Ronen Festinger

Es scheint, dass das Nuget-Paket Microsoft.Owin.Security.Facebook Version 3.0.1 mit Facebook-Login nicht mehr funktioniert.

Aktualisieren Sie dieses Paket auf die Vorversion 3.1.0. Sie können Folgendes verwenden:

Installationspaket Microsoft.Owin.Security.Facebook -Pre

19
Luke

Wie andere richtig erwähnt haben, liegt dies meistens daran, dass Sie keine Berechtigung für die Google+ API haben. Hier erfahren Sie, wie Sie die Genehmigung für ein Projekt in Google API Manager für die Google+ API erhalten

Schritt 1. Wählen Sie in der oberen Combobox Ihr Projekt aus und gehen Sie zu Dashboard> API aktivieren  enter image description here

Schritt 2: Suchen Sie nach Google Plus und wählen Sie es aus  enter image description here

Schritt 3: Aktivieren Sie es!  enter image description here

wenn Sie zum Dashboard für dieses Projekt zurückkehren, können Sie die Liste der aktivierten APIs für dieses Projekt unten sehen  enter image description here

Das hat mein Problem gelöst:

Aktivieren Sie die Google+ API. Dies ist ein Problem und ist die Hauptursache des Problems in der Frage hier. Wenn Sie dies nicht tun, ist es leicht zu übersehen, dass die Anforderung an /account/ExternalLoginCallback&error=access_denied enthält das Google+ Basisprofil des Nutzers. Ich kann nicht sagen, wessen Fehler das ist, von Google oder Microsoft.

Um die Google+ API in der Entwicklerkonsole zu aktivieren, klicken Sie links auf APIs, suchen Sie nach Google+, klicken Sie darauf und klicken Sie auf Aktivieren.

3
Hugh Proctor

Ich weiß, es ist dumm, aber nach einem langen Kampf löste ein Neustart IIS das Problem für mich.

3
Omri

Ich habe es zum Laufen gebracht, indem ich einfach alle Nugget-Pakete in der Anwendung aktualisiert habe.

Ich bin heute zu diesem Problem gekommen und es stellte sich heraus, dass ich den Remote-Cookie definiert habe, nachdem ich die Anbieter zugewiesen habe.

Stellen Sie sicher, dass Sie platzieren ...

app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

vor...

app.UseFacebookAuthentication(
                   appId: "",
                   appSecret: "");
1
Hagge

Ich habe folgendes getan, damit es funktioniert. 

Melden Sie sich beim Entwicklerportal an, suchen Sie Ihre Anwendung und gehen Sie wie folgt vor. 

App-Details> App-zentrierte gelistete Plattformen> Wählen Sie Ja für die Website aus

1
tony

Für mich war ich migriert und alt, aber funktionierte .NET 4.6.1 MVC-Website auf Core 1.1. Die Arbeit wurde unterbrochen, bevor ich sie zum Laufen bringen konnte. Als ich sie wieder aufnahm, migrierte ich auf 2.x.

Mein Problem war, dass der Rückruf von Google mit einem 404 von meiner Site beantwortet wurde. Ich dachte, es sollte AccountController.ExternalLoginCallback drücken, also fügte ich eine [Route(...)] hinzu, und tatsächlich war Googles Rückruf erfolgreich.

Dies traf dann die in dieser Zeile zurückgegebene null (welche Art von Maniac gibt eine null zurück?)

var externalLoginInfo = await this.SignInManager.GetExternalLoginInfoAsync();

Ich habe es rückgängig gemacht, um unter der Motorhaube herauszufinden, dass es letztendlich den Handler für ExternalScheme bekommt, der für mich der Handler für Kekse war!

Es schien alles falsch zu sein und ich hatte das Gefühl, dass die Middleware nur den Rückruf-URI abfangen sollte, also entfernte ich mein [Route(...)] und das 404 -Problem kam zurück.

Ich fand dann, dass ich dieses während des Starts hinzufügen muss.

applicationBuilder.UseAuthentication();

Dies löst den 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 wird AccountController.ExternalLoginCallback erneut durch Magie aufgerufen, aber ich bin wieder beim Rückgabewert null.

Ich habe diesen Code über der anstößigen Zeile eingefügt. Dies ist im Wesentlichen das, was unter der Haube passiert (siehe Microsoft-Code auf GitHub). Interessanterweise ist h 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 mich in GitHub einarbeite und den internen Code kopiere, der auf meinem Controller ausgeführt wird, kann ich feststellen, dass in meinen Behauptungen ClaimTypes.NameIdentifier nicht gefunden wird. Dies ist das ProviderKey, das später verwendet wird.

Hmm ....

Besorgt, dass ich alten 1.x 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 mache weiter mit dem, was ich habe.

Als Nächstes werde ich untersuchen, wie Sie zusätzliche JSON-Nutzlastelemente von Google-Nutzern in die Ansprüche einbinden. Ich denke, wenn meine Google-Konto-ID (numerisch, denke ich) zugeordnet wurde, 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 endlich gelöst, indem ich eine "Anspruchsaktion" hinzugefügt habe, um meine Google-ID aus dem von Google zurückgegebenen JSON herauszuholen!

serviceCollection.AddAuthentication(IdentityConstants.ExternalScheme)
    .AddGoogle(googleOptions =>
    {
        Configuration.Bind("OAuth2:Providers:Google", googleOptions);

        googleOptions.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "sub", "string");
    })
    .AddExternalCookie();

Das Feld sub enthält, was letztendlich in der Forderung nameidentifier und dann in der Forderung ProviderKey endet, die die AccountController haben möchte.

0
Luke Puplett

Für diejenigen, die dieses Problem für Web Api haben. Andere Lösungen helfen nicht AuthenticationManager.GetExternalLoginInfoAsync(); gibt immer null zurück, auch wenn Google plus API aktiviert ist.

verwenden Sie diese benutzerdefinierte Funktion, um logininfo abzurufen. Offensichtlich hat Microsoft einen Fehler für GetExternalLoginInfoAsync, wenn über Web-API angefragt wird.

private async Task<ExternalLoginInfo> AuthenticationManager_GetExternalLoginInfoAsync_WithExternalBearer()
        {
            ExternalLoginInfo loginInfo = null;

            var result = await Authentication.AuthenticateAsync(DefaultAuthenticationTypes.ExternalBearer);

            if (result != null && result.Identity != null)
            {
                var idClaim = result.Identity.FindFirst(ClaimTypes.NameIdentifier);
                if (idClaim != null)
                {
                    loginInfo = new ExternalLoginInfo()
                    {
                        DefaultUserName = result.Identity.Name == null ? "" : result.Identity.Name.Replace(" ", ""),
                        Login = new UserLoginInfo(idClaim.Issuer, idClaim.Value)
                    };
                }
            }
            return loginInfo;
        }
0
batmaci

Es ist richtig, dass Sie Google Plus Enabled benötigen. Das große Ding für mich war die Projekt-URL. Öffnen Sie das Eigenschaftenfenster (Ansicht -> Eigenschaftenfenster) in VS, klicken Sie mit der rechten Maustaste auf das Projekt und wählen Sie Eigenschaften aus. Kopieren Sie in einem kleinen Eigenschaftenfenster Ihre SSL-URL, und wählen Sie dann im größeren Eigenschaftenfenster die Registerkarte "Web" aus, und fügen Sie diese URL in die Projekt-URL ein.

Das Problem wurde für mich behoben.

Weitere Informationen finden Sie unter: https://docs.Microsoft.com/en-us/aspnet/mvc/overview/security/create-an-aspnet-mvc-5-app-with-facebook-and-google-oauth2 -und-openid-anmelden

0

Obwohl die obigen Antworten alle gut sind, funktionierte in meinem Fall nichts davon - ich hatte die Google-Einstellungen überprüft und nochmals überprüft und stimmte mit Chris Moschini überein, dass es viele irreführende Informationen gibt. 

Für mich war es ein echter Moment, als ich merkte, dass mein Out of Process State-Service nicht gestartet wurde ! Keine Fehler (da ein Login das erste war, was ich nach einem Neustart versuchte, bei dem der Statusdienst auf dem Computer auf manuellen Start eingestellt ist), nur ein Nullwert aus GetExternalLoginInfoAsync

Hoffe, das hilft jemand anderem.

0
JJones

Ich wollte auch dazu beitragen. Ich habe das erst kürzlich zum Laufen gebracht. Ich hatte das Problem, dass GetExternalLoginInfoAsync null zurückgab, jedoch nur in der Produktion.

Nach langem Suchen fand ich endlich meine Antwort, es war einfach ein Problem mit meiner Datenbank. In der Produktion hatte ich die falsche Verbindungszeichenfolge festgelegt, sodass die Verbindung nicht ordnungsgemäß hergestellt werden konnte. Das einzige, was passiert ist, war, dass GetExternallLoginInfoAsync null zurückgab. Überprüfen Sie in diesem Fall Ihre Datenbankverbindungszeichenfolge!

Auch auf einer Nebenbemerkung war das einzige, was nötig war, um diese Funktion zum Laufen zu bringen:

  • Richten Sie ein Projekt in der Google-Konsole ein
  • Aktivieren Sie die Google+ API
  • Kopieren Sie Ihre Client-ID und Ihr Client-Secret in die Datei Startup.Auth.cs.

Sie müssen HTTPS nicht aktivieren, Sie müssen keine benutzerdefinierten Routen erstellen. Stellen Sie jedoch sicher, dass Ihre Datenbank ordnungsgemäß funktioniert!

0
Johan O

Nach langem Suchen und Verkratzen sowie zahlreichen Antworten auf Heringsherde auf Stackoverflow habe ich schließlich alle Optionen auf meiner Google-Dev-Konsole durchgesehen und auf der Google + API-Übersichtsseite einen kleinen blauen [Aktivieren] -Button entdeckt. Ich habe darauf geklickt, und es hat funktioniert. Vergessen Sie den ganzen Quatsch, den Sie über Callback-URLs und Routenkonfigurationen gelesen haben. OWIN überschreibt in jedem Fall den Standard-/Signin-Google-Redirect-URL von google und sendet Sie zurück an ExternalLoginCallback. Bleiben Sie einfach bei der Standardimplementierung. Alles wird gut, solange Sie Ihre Google + API aktivieren.

0
Graham Walker