2017-09-11 4 views
0

Je suis en mesure de configurer l'authentification .NET de base Instagram 1 en utilisant this library, mais je ne peux pas sembler le faire fonctionner dans .NET de base 2.OAuth GetExternalLoginInfoAsync retourne Instagram toujours null dans .NET Core 2.0

Il ne semble pas y avoir de bibliothèques Instagram OAuth compatibles avec .NET Core 2.0, donc j'essaie d'utiliser la méthode intégrée AddOAuth. Je suis capable d'obtenir tout pour s'authentifier sans problème, mais pour une raison quelconque, ma méthode GetExternalLoginInfoAsync dans LinkLoginCallback renvoie toujours null. Comme tout ce qui se passe dans AspNetCore.Authentication, je suppose que mon installation et la configuration ne sont pas correctes (ou manquant quelque chose de critique), ou cette solution ne va pas fonctionner pour une autre raison.

Ma config dans ConfigureServices ressemble à ceci:

services.AddAuthentication().AddOAuth("Instagram", "Instagram", options => 
     { 
      options.ClientId = "MYID"; 
      options.ClientSecret = "MYSECRET"; 
      options.AuthorizationEndpoint = "https://api.instagram.com/oauth/authorize/"; 
      options.CallbackPath = "/signin-instagram"; 
      options.TokenEndpoint = "https://api.instagram.com/oauth/access_token"; 
      options.Scope.Add("basic"); 
      options.ClaimsIssuer = "Instagram"; 
      options.UserInformationEndpoint = "https://api.instagram.com/v1/users/self"; 
     }); 

Quelqu'un at-il été en mesure d'authentifier avec succès dans .NET Instagram Core 2.0? Toute aide serait grandement appréciée!

+0

Avez-vous déjà obtenu cela au travail? – Jon

+0

@Jon pas la manière intégrée, non. A dû le faire avec un flux de travail personnalisé. –

+0

Bravo! Cela vous dérangerait-il de partager comme réponse acceptée? – Jon

Répondre

1

Pas spécifiquement pour Instagram mais j'ai une validation OAuth personnalisée qui fonctionne pour Twitch en utilisant une configuration similaire à celle ci-dessus. Je recevais les mêmes erreurs Null de GetExternalLoginInfoAsync et il y avait un certain nombre d'étapes que je devais passer pour le faire fonctionner.

En fin de compte, j'ai trouvé le problème en regardant le code source pour la méthode GetExternalLoginInfoAsync trouve ici - Microsoft.AspNetCore.Identity.SignInManager.cs

  1. La première chose que je trouve est littéralement sur la première ligne de la méthode

    var auth = await Context.AuthenticateAsync(IdentityConstants.ExternalScheme); 
    

    La méthode est configurée pour utiliser toujours la constante ExternalScheme donc si vous définissez un SignInScheme personnalisé dans votre Startup.cs il ne sera pas utilisé lors de l'appel de cette méthode. Laisser le paramètre SignInScheme défini comme valeur par défaut ne semblait pas fonctionner pour moi.

  2. La LoginProviderKey était null.

    if (auth?.Principal == null || items==null||!items.ContainsKey(LoginProviderKey)){return null;} 
    
  3. Et après la fixation qui précède, je trouve que aucune réclamation étaient mis si je devais mettre en place que manuellement. J'ai trouvé un exemple sur une autre question Stackoverflow - AddOAuth linkedin dotnet core 2.0

S'il vous plaît voir ci-dessous mon code final:

Startup.cs Configuration OAuth Middleware

Dans le démarrage, je mis le SignInScheme à utilisez la valeur IdentityConstants.ExternalScheme et ajoutez l'événement de configuration Claims du client dans OnCreatingTicket.

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) 
      .AddOAuth("Twitch", "Twitch", o => 
       { 
        o.SignInScheme = IdentityConstants.ExternalScheme; 
        o.ClientId = "MY CLIENT ID"; 
        o.ClientSecret = "MY CLIENT SECRET"; 
        o.CallbackPath = "/signin-twitch"; 
        o.ClaimsIssuer = "Twitch"; 
        o.AuthorizationEndpoint = "https://api.twitch.tv/kraken/oauth2/authorize"; 
        o.TokenEndpoint = "https://api.twitch.tv/api/oauth2/token"; 
        o.UserInformationEndpoint = "https://api.twitch.tv/helix/users"; 
        o.Scope.Add("openid"); 
        o.Scope.Add("user:read:email"); 

        o.Events = new Microsoft.AspNetCore.Authentication.OAuth.OAuthEvents 
        { 
         OnCreatingTicket = async context => 
         { 
          var request = new HttpRequestMessage(HttpMethod.Get, context.Options.UserInformationEndpoint); 
          request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", context.AccessToken); 
          request.Headers.Add("x-li-format", "json"); 

          var response = await context.Backchannel.SendAsync(request, context.HttpContext.RequestAborted); 
          response.EnsureSuccessStatusCode(); 
          var user = JObject.Parse(await response.Content.ReadAsStringAsync()); 

          var data = user.SelectToken("data")[0]; 

          var userId = (string)data["id"]; 
          if (!string.IsNullOrEmpty(userId)) 
          { 
           context.Identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, userId, ClaimValueTypes.String, context.Options.ClaimsIssuer)); 
          } 

          var formattedName = (string)data["display_name"]; 
          if (!string.IsNullOrEmpty(formattedName)) 
          { 
           context.Identity.AddClaim(new Claim(ClaimTypes.Name, formattedName, ClaimValueTypes.String, context.Options.ClaimsIssuer)); 
          } 

          var email = (string)data["email"]; 
          if (!string.IsNullOrEmpty(email)) 
          { 
           context.Identity.AddClaim(new Claim(ClaimTypes.Email, email, ClaimValueTypes.String, 
            context.Options.ClaimsIssuer)); 
          } 
          var pictureUrl = (string)data["profile_image_url"]; 
          if (!string.IsNullOrEmpty(pictureUrl)) 
          { 
           context.Identity.AddClaim(new Claim("profile-picture", pictureUrl, ClaimValueTypes.String, 
            context.Options.ClaimsIssuer)); 
          } 
         } 
        }; 
       }); 

AccountController.cs créant le Défi

Quand nous émettons le défi que nous devons également inclure la valeur LoginProvider.

public IActionResult LoginWithTwich(string returnUrl = null) 
    { 

     var authProperties = new AuthenticationProperties 
     { 
      RedirectUri = Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl }), 
      Items = { new KeyValuePair<string, string>("LoginProvider", "Twitch") } 
     }; 

     return Challenge(authProperties, "Twitch"); 
    } 

AccountController.cs Manipulation du Callback

Enfin, lorsque nous traitons le rappel de la méthode GetExternalLoginInfoAsync ne retourne plus nulle.

public async Task<IActionResult> ExternalLoginCallback(string returnUrl = null) 
    { 
     ExternalLoginInfo info = await _signInManager.GetExternalLoginInfoAsync(); 
     //to sign the user in if there's a local account associated to the login provider 
     var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false); 
     if (!result.Succeeded) 
     { 
      return RedirectToAction("ConfirmTwitchLogin", new { ReturnUrl = returnUrl }); 
     } 
     if (string.IsNullOrEmpty(returnUrl)) 
     { 
      return Redirect("~/"); 
     } 
     else 
     { 
      return RedirectToLocal(returnUrl); 
     } 
    }