web-dev-qa-db-fra.com

GetExternalLoginInfoAsync de OWIN renvoie toujours null

J'ai créé une nouvelle application Web MVC5 et lorsque j'essaie de me connecter à Google ou à Facebook, l'action ExternalLoginCallback de la AccountController est appelée, mais GetExternalLoginInfoAsync() renvoie toujours null:

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

Comme il est toujours nul, il redirige la page de connexion et le processus recommence. Comment puis-je réparer cela?

63
VineetYadav

OK, j'ai découvert pourquoi c'est nul. Vous devez activer Google + API dans la console Google. Assurez-vous également que la clé secrète n'est pas concaténée avec un espace à la fin après l'avoir collée dans votre code. Pourquoi ne peuvent-ils pas renvoyer une erreur normale? Je ne sais pas.

45
Ronen Festinger

Il semble que le package Nuget Microsoft.Owin.Security.Facebook version 3.0.1 ne fonctionne plus avec Facebook Login.

Mettez à jour ce paquet vers la version 3.1.0 de pré-version, vous pouvez utiliser ce qui suit:

Kit d'installation Microsoft.Owin.Security.Facebook -Pre

19
Luke

Comme d'autres l'ont mentionné à juste titre, la plupart du temps, c'est parce que vous n'avez pas l'autorisation de l'API Google+. Voici comment obtenir l'autorisation pour un projet dans Google API Manager vers l'API Google+.

Étape 1. Sélectionnez Votre projet dans la liste déroulante supérieure et accédez à Tableau de bord> Activer l'API  enter image description here

Étape 2: Recherchez Google plus et sélectionnez-le  enter image description here

Étape 3: Activez-le!  enter image description here

si vous revenez au tableau de bord pour ce projet, vous pouvez voir la liste des API activées pour ce projet en bas  enter image description here

7

Cela a résolu mon problème:

Activer l'API Google+. Ceci est un piège et constitue la cause fondamentale du problème de la question ici. Si vous ne le faites pas, il est facile de rater le fait que Request to /account/ExternalLoginCallback inclut &error=access_denied, et c'est parce que Google a refusé une demande de permission OWIN faite pour le profil de base Google+ de l'utilisateur. Je ne peux pas dire à qui la faute, Google ou Microsoft.

Pour activer l'API Google+ dans la console des développeurs, cliquez sur les API à gauche, recherchez Google, cliquez dessus et appuyez sur Activer.

3
Hugh Proctor

Je sais que c'est idiot, mais après une longue lutte, redémarrer IIS a résolu le problème pour moi.

3
Omri

Je l'ai fait fonctionner en mettant simplement à jour tout le paquet de nugget dans l'application et cela a fonctionné.

3

J'ai rencontré ce problème aujourd'hui et il s'est avéré que j'ai défini le cookie à distance après avoir affecté les fournisseurs.

Assurez-vous de placer ...

app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

avant...

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

J'ai fait ce qui suit pour le faire fonctionner. 

Ouvrez une session sur le portail des développeurs, localisez votre application et procédez comme suit. 

Détails de l'application> Plates-formes répertoriées centrées sur l'application> Sélectionnez Oui pour le site Web.

1
tony

Pour moi, je migrais et suis vieux, mais je travaille avec le site Web .NET 4.6.1 MVC en version 1.1. Le travail s'est arrêté avant que je puisse le faire fonctionner. Lorsque je l'ai repris, je migrais alors vers la version 2.x.

Mon problème était que le rappel de Google a été rencontré avec un 404 de mon site. Je pensais que c'était censé frapper AccountController.ExternalLoginCallback alors j'ai ajouté un [Route(...)] à celui-ci et bien sûr, le rappel de Google a déclenché l'action.

Ceci a ensuite frappé la null retournée dans cette ligne (quel genre de maniaque renvoie une null?)

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

J'ai inversé l'ingénierie pour trouver sous le capot son gestionnaire final pour ExternalScheme qui pour moi était le gestionnaire de cookies!

Tout semblait faux et j'avais l'impression que le middleware était censé intercepter l'URI de rappel; j'ai donc supprimé ma [Route(...)] et le problème 404 est revenu.

J'ai alors constaté que je devais ajouter ceci au démarrage.

applicationBuilder.UseAuthentication();

Cela résout le 404 mais donne un autre problème.

AuthenticationScheme n'a pas été spécifié et aucun DefaultSignInScheme n'a été trouvé.

En ajoutant un schéma par défaut ici, je résous l'erreur ci-dessus.

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

Maintenant, AccountController.ExternalLoginCallback est à nouveau appelé par magie mais je reviens à la valeur de retour null.

J'ai ajouté ce code au-dessus de la ligne incriminée, qui correspond essentiellement à ce qui se passe sous le capot (en examinant le code de Microsoft sur GitHub). Fait intéressant, h est de type CookieAuthenticationHandler et a contient toutes mes revendications et les informations de Google à l'intérieur!

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();

En fouillant dans GitHub et en copiant en collant le code interne dans son contrôleur, je constate qu'il ne parvient pas à trouver ClaimTypes.NameIdentifier dans mes revendications, il s'agit de la ProviderKey utilisée ultérieurement.

Hmm ....

Concerné J'utilisais l'ancien code 1.x AccountController avec des bits d'identité 2.x plus récents. J'ai trouvé quelques exemples qui utilisent encore ce matériel, ainsi que des exemples qui utilisent Razor Pages pour tout cela également. Je vais continuer avec ce que j'ai.

Je vais donc ensuite examiner la possibilité de mapper des éléments de charge utile JSON d'utilisateur Google supplémentaires dans les revendications. Je pense que si mon identifiant de compte Google (numérique, je suppose) était mappé, tout fonctionnerait.

https://docs.Microsoft.com/en-us/aspnet/core/security/authentication/social/additional-claims?view=aspnetcore-2.2

Correctif final

J'ai finalement résolu le problème en ajoutant une "action de réclamation" pour extraire mon identifiant Google du fichier JSON renvoyé par Google!

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

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

Le champ sub contient ce qui finit par se retrouver dans la revendication nameidentifier, puis dans la ProviderKey que veut le AccountController.

0
Luke Puplett

Pour ceux qui rencontrent ce problème pour Web Api. D’autres solutions n’aident pas AuthenticationManager.GetExternalLoginInfoAsync(); renvoie toujours la valeur null même si google plus api est activé.

utilisez cette fonction personnalisée pour obtenir logininfo. De toute évidence, Microsoft a un bogue pour GetExternalLoginInfoAsync lorsqu’il demande via une API Web.

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

Il est vrai que vous allez avoir besoin de Google plus activé. Le gros problème pour moi était l'URL du projet. Ouvrez la fenêtre de propriétés (Affichage -> Fenêtre de propriétés) dans VS, puis cliquez avec le bouton droit de la souris sur le projet et sélectionnez Propriétés. Dans une petite fenêtre de propriétés, copiez votre URL SSL, puis dans la fenêtre de propriétés plus grande, sélectionnez l'onglet Web et collez cette URL dans l'URL du projet.

Correction du problème pour moi.

Voir plus en détail: 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
AtLeastTheresToast

Bien que les réponses ci-dessus soient toutes bonnes, dans mon cas, aucune de ces solutions n'a fonctionné - j'avais vérifié et revérifié les paramètres de Google et je suis d'accord avec Chris Moschini sur le fait qu'il existe de nombreuses informations trompeuses. 

Pour moi, c’est un moment très difficile lorsque j’ai réalisé que mon service Hors processus état n’était pas lancé ! Aucune erreur (la connexion étant la première chose que j'essayais après un redémarrage, lorsque le service d'état est configuré pour un démarrage manuel sur la machine), il suffit d'un Null de GetExternalLoginInfoAsync

J'espère que cela aide quelqu'un d'autre.

0
JJones

Je voulais aussi contribuer à celui-ci. Je viens de le faire fonctionner récemment. J'ai eu le problème avec GetExternalLoginInfoAsync renvoyant null, mais uniquement en production.

Après de nombreuses recherches, j'ai finalement trouvé ma réponse. Il s'agissait simplement d'un problème de base de données. En production, j'avais défini la mauvaise chaîne de connexion afin qu'elle ne se connecte pas correctement, mais elle était fondamentalement silencieuse. La seule chose qui s'est produite est que GetExternallLoginInfoAsync a renvoyé la valeur null. Vérifiez donc votre chaîne de connexion à la base de données si cela se produit!

Également sur un sidenote, la seule chose qui était nécessaire pour que cela fonctionne était:

  • Configurer un projet dans la console Google
  • Activer l'API Google+
  • Copiez votre identifiant client et votre secret client dans le fichier Startup.Auth.cs.

Vous ne devez pas activer HTTPS, vous ne devez pas créer d'itinéraires personnalisés. Mais assurez-vous que votre base de données fonctionne correctement!

0
Johan O

Après beaucoup de recherches et de grincements de tête ainsi que de nombreuses réponses au hareng rouge ici sur Stackoverflow, j'ai finalement examiné toutes mes options sur ma console de développement Google et découvert un petit bouton bleu [Enable] sur la page de présentation de l'API Google +. J'ai cliqué dessus et hop, ça a fonctionné. Oubliez toutes les informations inutiles que vous avez lues sur les configs d'URL de rappel et d'itinéraires, OWIN écrase en tout cas la redirection par défaut/signin-google de Google et vous renvoie à ExternalLoginCallback. Tenez-vous en à la mise en œuvre par défaut, tout ira bien tant que vous activez votre API Google +.

0
Graham Walker