GetExternalLoginInfoAsync von OWIN gibt immer null zurück


69

Ich habe eine neue MVC5-Webanwendung erstellt. Wenn ich versuche, mich mit Google oder Facebook anzumelden, wird die ExternalLoginCallbackAktion in AccountControlleraufgerufen, gibt jedoch GetExternalLoginInfoAsync()immer null zurück:

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

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


Schauen Sie sich Folgendes an: asp.net/mvc/tutorials/mvc-5/… . Ich folgte ihm gestern ohne Probleme
Felipe Miosso

Haben Sie überprüft, ob der richtige Anbieter an ChallengeResult von ExternalLogin ActionResult übergeben wird?
Santosh

2
Das gleiche Problem erleben. Und ja, der Anbieter ist korrekt. Ich klicke auf Anmelden, Ich werde zu Facebook umgeleitet, ich melde mich an und dann werde ich zur Methode weitergeleitet ... mit einer Null-Anmeldung.
NVentimiglia

1
Das gleiche Problem erleben. Es behebt das Problem, nachdem ich den IIS neu gestartet habe. Gibt es eine geeignete Lösung für dieses Problem?
Lee

7
Ich habe das gleiche Problem, ich habe vergessen, die Google + API
einzuschalten

Antworten:


105

Damit OWIN Google Login auf einer Standard-Visual Studio 2013, ASP.Net MVC5-Site 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 ein blah/signin-google.
    Wichtige Hinweise zu Dingen, die Sie nicht tun müssen:

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

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

Wenn Ihre Website beispielsweise me.com war, haben Sie möglicherweise diese drei Rückruf-URLs in der Google Developer Console:

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

Die erste enthält die Portnummer, die VS Ihnen für Ihr Projekt gegeben hat.

  1. Aktivieren Sie die Google+ API . Dies ist ein verstecktes Problem eines Gotchas und die Hauptursache für das Problem in der Frage hier. Wenn Sie dies nicht tun, ist es leicht zu übersehen, dass die Anfrage /account/ExternalLoginCallbackenthalten ist &error=access_denied, und das liegt daran, dass Google Nein gesagt hat Eine Berechtigungsanforderung OWIN für das Google+ Basisprofil des Nutzers. Ich kann nicht sagen, wessen Schuld dies ist, die 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. Ja, das müssen Sie wirklich tun. Sie werden abgespritzt, wenn Sie das nicht tun.

  1. Fügen Sie die ClientId und ClientSecret hinzu, die Google Ihnen in der Entwicklerkonsole zu Startup.Auth gegeben hat. Verbessern Sie dabei 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 noch einmal wiederholen, es gibt viele Antworten zu diesem Thema und zu ähnlichen Problemen, bei denen OWIN / Google nicht funktioniert, und fast alle 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-googleauf einen anderen Ort zu verweisen oder eine andere Rückruf-URL zu verwenden, und Sie sollten auf keinen Fall versuchen, diese direkt mit /account/externallogincallbackoder zu verknüpfen externalloginconfirmation, da diese /signin-googleSchritte von den OWIN / Google-Prozessen getrennt sind und diese erforderlich sind.


11
Nummer drei hat es für mich getan. Leider wusste ich, dass dies das Problem in der Vergangenheit war, hatte es aber vergessen ... und ja, stimme vollkommen zu, dass dies ab **** ist. Vielen Dank für die Liste.
Roboto1986

4
Danke danke danke! Hat funktioniert, ja ANABLE Google+ API, es hat auch ohne "Codeverbesserung" funktioniert. Tolle detaillierte Antwort!
Pawel Cioch

1
Wenn ich dich 1000 Mal positiv bewerten könnte, würde ich es tun. Vielen Dank!
Giovanni Galbo

4
Funktioniert bei mir nicht Es ist tatsächlich unmöglich, eine AppID und AppSecret zu erstellen, ohne die Google+ API zu aktivieren. Ich habe es aktiviert und konnte das Geheimnis und die ID erstellen, werde aber immer noch zur Anmeldeseite zurückgeleitet.
Tutiplain

2
Ich habe es aktiviert, aber es funktioniert immer noch nicht. Ich denke darüber nach, den Oauth-Flow manuell auszuführen, da dies entweder in Owin oder in den Projektvorlagen in Visual Studio ein Fehler zu sein scheint.
Tutiplain

46

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 nicht mit einem Leerzeichen am Ende verknüpft ist, nachdem Sie ihn in Ihren Code eingefügt haben. Warum können sie keinen normalen Fehler zurückgeben? Ich weiß es nicht.


6
Dies löste das Problem sofort. Guter Fund, danke.
James Mauldin

Jetzt, wo ich genau hinschaue, sehe ich, dass dieser Schritt in den Anweisungen auf asp.net deutlich angegeben ist .
James Mauldin

Ja, aber ich dachte, es ist nicht obligatorisch. Auf jeden Fall ist der Zusammenhang zwischen diesem und dem angezeigten Fehler nicht klar.
Ronen Festinger

Ja, ich habe alle möglichen verrückten Antworten gesehen, aber das ist die richtige für mich.
Papa Burgund

Sie, mein Herr, sind ein Gott!
Kris

19

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

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

Installationspaket Microsoft.Owin.Security.Facebook -Pre


Ich bin heute auch aus dem Nichts darauf gestoßen, und das Update auf den RC von 3.1.0 hat auch für mich funktioniert.
Chris Searles

Ich bin froh, geholfen zu haben :)
Luke

2
Crikey, ich hoffe, sie beheben das Problem. Sie haben die ganze Nacht damit verbracht, URLs neu zu konfigurieren, um herauszufinden, was ich versehentlich geändert habe, seit es das letzte Mal funktioniert hat, als ich herumgespielt habe. Ihr Vorschlag hat funktioniert. Noch keine aktualisierte Version später als 3.0.1 nach NuGet zu installieren
Richard

1
Nachdem ich so ziemlich alles auf Stapelüberlauf ausprobiert und ungefähr 3 Stunden verschwendet hatte, war dies die endgültige Lösung für mich. Danke :)
Dan Cook

1
Ein Upgrade auf 3.1 hat mein Problem behoben. Vielen Dank, dass Sie mir viele schmerzhafte Stunden beim Debuggen erspart haben!
Johnny Rose

7

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 Berechtigung für ein Projekt im 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 Geben Sie hier die Bildbeschreibung ein

Schritt 2: Suchen Sie nach Google Plus und wählen Sie es aus Geben Sie hier die Bildbeschreibung ein

Schritt 3: Aktivieren Sie es! Geben Sie hier die Bildbeschreibung ein

Wenn Sie für dieses Projekt zum Dashboard zurückkehren, sehen Sie unten die Liste der aktivierten APIs für dieses Projekt Geben Sie hier die Bildbeschreibung ein


4

Ich habe es zum Laufen gebracht, indem ich einfach das gesamte Nugget-Paket in der Anwendung aktualisiert habe, und es hat funktioniert.


Dies funktionierte auch für mich, nachdem ich alles andere ausprobiert hatte, was hier erwähnt wurde. Ich habe die OWIN-Pakete von v4.0.0 auf v4.0.1 aktualisiert und dann hat es angefangen zu funktionieren.
Christianantober

3

Ich weiß, dass es albern ist, aber nach einem langen Kampf löste der Neustart von IIS das Problem für mich.


Das gleiche gilt hier, aber das Problem kehrte nach einer Weile (Tagen) zurück. Es hat einige Zeit gut funktioniert, dann hört es plötzlich einfach auf und eine Aktualisierung des App-Pools löst es wieder. Sehr merkwürdig.
Patrick

Dies löste das Problem für mich. Hoffentlich funktioniert es jetzt weiter. stackoverflow.com/a/20948631/155758
Patrick

3

Dies löste mein Problem:

Aktivieren Sie die Google+ API. Dies ist ein Gotcha und die Hauptursache für das Problem in der Frage hier. Wenn Sie dies nicht tun, ist es leicht zu übersehen, dass die Anforderung /account/ExternalLoginCallbackenthalten ist &error=access_denied, und das liegt daran, dass Google zu einer Berechtigungsanforderung, die OWIN für den Benutzer gestellt hat, Nein gesagt hat Google+ Basisprofil. Ich kann nicht sagen, wessen Schuld dies ist, die 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.


1

Ich habe Folgendes getan, um es zum Laufen zu bringen.

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

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


1

Ich bin heute auf dieses Problem gestoßen und es stellte sich heraus, dass ich das Remote-Cookie definiert habe, nachdem ich die Anbieter zugewiesen hatte.

Stellen Sie sicher, dass Sie ...

app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

Vor...

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

1

Für diejenigen, die dieses Problem für Web-Api haben. Andere Lösungen helfen nicht dabei, AuthenticationManager.GetExternalLoginInfoAsync();immer null zurückzugeben, selbst wenn Google Plus API aktiviert ist.

Verwenden Sie diese benutzerdefinierte Funktion, um Anmeldeinformationen zu erhalten. Offensichtlich hat Microsoft einen Fehler für GetExternalLoginInfoAsync beim Anfordern über die Web-API.

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;
        }

1
Vielen Dank, dass dies mein Problem gelöst hat. Microsoft muss sich diesen Fehler ansehen
Samuel Moshie

0

Obwohl die obigen Antworten alle gut sind, hat in meinem Fall keines davon funktioniert - ich habe die Google-Einstellungen überprüft und doppelt überprüft und bin Chris Moschini zugestimmt, dass es viele irreführende Informationen gibt.

Für mich war es ein Moment, als mir klar wurde, dass mein Out of Process-Statusdienst nicht gestartet wurde ! Keine Fehler (da ein Login das erste war, was ich nach einem Neustart versuchte, bei dem der Statusdienst auf manuellen Start auf dem Computer eingestellt ist), nur eine Null vonGetExternalLoginInfoAsync

Hoffe das hilft jemand anderem.


0

Nach langem Suchen und Kopfkratzen sowie dem Befolgen zahlreicher Red Herring-Antworten hier auf Stackoverflow ging ich schließlich alle meine Optionen auf meiner Google Dev-Konsole durch und entdeckte eine kleine blaue Schaltfläche [Aktivieren] auf der Google + API-Übersichtsseite. Ich habe darauf geklickt und hey Presto es hat funktioniert. Vergessen Sie all den Quatsch, den Sie über Rückruf-URLs und Routenkonfigurationen gelesen haben. OWIN überschreibt auf jeden Fall die Google-Standard- / Anmelde-Google-Weiterleitungs-URL und sendet Sie zurück zu ExternalLoginCallback. Halten Sie sich einfach an die Standardimplementierung, alles ist gut, solange Sie Ihre Google + API aktivieren.


0

Ich wollte auch dazu beitragen. Ich habe das erst kürzlich zum Laufen gebracht. Ich hatte das Problem, dass GetExternalLoginInfoAsync null zurückgab, aber 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 eingestellt, damit die Verbindung nicht richtig hergestellt werden konnte, aber es wurde im Grunde nichts darüber gesagt. Das einzige, was passiert ist, ist, dass GetExternallLoginInfoAsync null zurückgegeben hat. Überprüfen Sie in diesem Fall die Datenbankverbindungszeichenfolge!

Auch auf einer Nebenbemerkung war das einzige, was benötigt wurde, um dies 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-Geheimnis in die Datei Startup.Auth.cs.

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


0

Es ist wahr, 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 im kleinen Eigenschaftenfenster Ihre SSL-URL. Wählen Sie dann im größeren Eigenschaftenfenster die Registerkarte Web 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-and -openid-sign-on


0

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 404von meiner Website beantwortet wurde . Ich dachte, es sollte schlagen, AccountController.ExternalLoginCallbackalso fügte ich ein hinzu [Route(...)]und sicher traf Googles Rückruf die Aktion.

Dies traf dann die nullin 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 ExternalSchemeden 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 404Problem 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.ExternalLoginCallbackwird durch etwas Magie wieder aufgerufen, aber ich bin zurück zum nullRückgabewert.

Ich habe diesen Code über der betreffenden Zeile hinzugefügt, was im Wesentlichen unter der Haube geschieht (siehe Microsoft-Code auf GitHub). Interessanterweise hist es vom Typ CookieAuthenticationHandlerund aenthä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.NameIdentifierin 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 subFeld enthält, was schließlich im nameidentifierAnspruch und dann in dem endet, was ProviderKeyder AccountControllerwill.


0

In meinem Fall war die Lösung das Update des Nuget-Pakets Microsoft.Owin.Security und Microsoft.Owin.Security.Google


-1

Alle anderen Antworten haben dies für mich nicht gelöst. Wenn Sie sich also im selben Boot befinden, stellen Sie sicher, dass Ihre Registrierungscontroller-Aktion das RequireHttps-Attribut hat:

    // GET: /Account/LoginRegister
    [AllowAnonymous]
    [RequireHttps]
    public ActionResult LoginRegister()
    {
        return View(new RegisterLoginViewModel());
    }
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.