Instagram OAuth GetExternalLoginInfoAsync始终在.NET Core 2.0中返回null

时间:2017-09-11 14:44:18

标签: c# asp.net instagram asp.net-core-2.0 .net-core-2.0

我可以使用this library在.NET Core 1中配置Instagram身份验证,但我似乎无法在.NET Core 2中使用它。

似乎没有任何与.NET Core 2.0兼容的Instagram OAuth库,因此我尝试使用内置的AddOAuth方法。我能够在没有问题的情况下对所有内容进行身份验证,但由于某些原因,LinkLoginCallback中的GetExternalLoginInfoAsync方法始终返回null。因为所有这些都发生在AspNetCore.Authentication中我假设我的设置和配置不正确(或缺少一些关键的东西),或者这个解决方案由于某些其他原因而无法工作。

ConfigureServices中的我的配置如下所示:

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

有没有人能够在.NET Core 2.0中成功通过Instagram进行身份验证?任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:2)

不是专门用于Instagram,但我使用类似的设置为Twitch进行了自定义OAuth验证。

我从GetExternalLoginInfoAsync获得了相同的Null错误,并且我需要执行许多步骤才能使其正常工作。

最后,我通过查看此处找到的GetExternalLoginInfoAsync方法的源代码找到了问题 - Microsoft.AspNetCore.Identity.SignInManager.cs

  1. 我发现的第一件事就是在方法的第一行

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

    该方法设置为始终使用ExternalScheme 如果在Startup.cs中设置自定义SignInScheme,则为常量 调用此方法时不会使用它。将SignInScheme设置为默认值也似乎对我没有用。

  2. LoginProviderKey为空。

    if (auth?.Principal == null || items==null||!items.ContainsKey(LoginProviderKey)){return null;}
    
  3. 在修复上述内容后,我发现没有设置任何声明,因此我也必须手动设置。我在另一个Stackoverflow问题上找到了一个例子 - AddOAuth linkedin dotnet core 2.0

  4. 请参阅下面的最终代码:

    Startup.cs配置OAuth中间件

    在Startup中,我将SignInScheme设置为使用IdentityConstants.ExternalScheme值,并在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

    当我们发出挑战时,我们还必须包含LoginProvider值。

    public IActionResult LoginWithTwich(string returnUrl = null)
        {
    
            var authProperties = _signInManager.ConfigureExternalAuthenticationProperties("Twitch", returnUrl);
    
            return Challenge(authProperties, "Twitch");
        }
    

    AccountController.cs处理回调

    最后,当我们处理回调时,GetExternalLoginInfoAsync方法不再返回null。

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

答案 1 :(得分:0)

为我工作(2.2版核心网络)

  1. 安装下一个软件包:

安装包AspNet.Security.OAuth.Instagram-版本2.0.1

  1. 注册客户端密钥(如用户秘密)

dotnet用户机密设置身份验证:Instagram:ClientId YourClientId

dotnet用户机密设置身份验证:Instagram:ClientSecret YourClientSecret

最后进入启动类:

services.AddAuthentication()
    .AddInstagram(instagramOptions =>
                {
                    instagramOptions.ClientId = Configuration["Authentication:Instagram:ClientId"];
                    instagramOptions.ClientSecret = Configuration["Authentication:Instagram:ClientSecret"];
                }
    );