简体   繁体   English

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

[英]Instagram OAuth GetExternalLoginInfoAsync always returns null in .NET Core 2.0

I'm able to configure Instagram authentication in .NET Core 1 using this library , but I can't seem to get it working in .NET Core 2. 我可以使用此库在.NET Core 1中配置Instagram身份验证,但似乎无法使其在.NET Core 2中运行。

There don't seem to be any Instagram OAuth libraries that are compatible with .NET Core 2.0 so I'm trying to use the built-in AddOAuth method. 似乎没有与.NET Core 2.0兼容的Instagram OAuth库,因此,我尝试使用内置的AddOAuth方法。 I'm able to get everything to authenticate without a problem, but for some reason my GetExternalLoginInfoAsync method in the LinkLoginCallback always returns null. 我能够毫无问题地进行所有身份验证,但是由于某种原因,LinkLoginCallback中的GetExternalLoginInfoAsync方法始终返回null。 As all of that stuff is happening in AspNetCore.Authentication I'm assuming either my setup and configuration is not correct (or missing something critical), or this solution isn't going to work for some other reason. 由于所有这些事情都是在AspNetCore.Authentication中发生的,因此我假设我的设置和配置不正确(或缺少一些关键内容),或者由于其他原因该解决方案无法正常工作。

My config in ConfigureServices looks like this: 我在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";
        });

Has anybody been able to successfully authenticate with Instagram in .NET Core 2.0? 有人能够在.NET Core 2.0中成功通过Instagram进行身份验证吗? Any help would be greatly appreciated! 任何帮助将不胜感激!

Not specifically for Instagram but I have got custom OAuth validation working for Twitch using a similar setup as above. 不是专门针对Instagram,但我已经使用上述类似的设置为Twitch使用了自定义OAuth验证。

I was getting the same Null errors from GetExternalLoginInfoAsync and there were a number of steps I had to go through to get it working. 我从GetExternalLoginInfoAsync收到了相同的Null错误,我必须经过许多步骤才能使其工作。

In the end I found the problem by looking at the source code for the GetExternalLoginInfoAsync method found here - Microsoft.AspNetCore.Identity.SignInManager.cs 最后,我通过查看此处找到的GetExternalLoginInfoAsync方法的源代码找到了问题-Microsoft.AspNetCore.Identity.SignInManager.cs

  1. The first thing I found is literally on the first line of the method 我发现的第一件事实际上是方法的第一行

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

    The method is set to use always the ExternalScheme constant so if you set a custom SignInScheme in your Startup.cs it wont be used when calling this method. 该方法设置为始终使用ExternalScheme常量,因此,如果在Startup.cs中设置自定义SignInScheme,则在调用此方法时将不会使用该常量。 Leaving SignInScheme set as the default value also didn't seem to work for me. 将SignInScheme设置为默认值似乎对我也不起作用。

  2. The LoginProviderKey was null. LoginProviderKey为空。

     if (auth?.Principal == null || items==null||!items.ContainsKey(LoginProviderKey)){return null;} 
  3. And after fixing the above I found that no Claims were being set so I had to set that up manually as well. 解决上述问题后,我发现没有设置任何索偿要求,因此我也必须手动进行设置。 I found an example of this on another Stackoverflow question - AddOAuth linkedin dotnet core 2.0 我在另一个Stackoverflow问题上找到了一个示例-AddOAuthlinkedin dotnet core 2.0

Please see below my final code: 请在下面查看我的最终代码:

Startup.cs Configuring OAuth Middleware Startup.cs配置OAuth中间件

In the Startup I set the SignInScheme to use the IdentityConstants.ExternalScheme value and added the customer Claims setup event in OnCreatingTicket. 在启动中,我将SignInScheme设置为使用IdentityConstants.ExternalScheme值,并在OnCreatingTicket中添加了客户Claims设置事件。

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 creating the Challenge AccountController.cs创建挑战

When we issue the challenge we also have to include the LoginProvider value. 发出挑战时,我们还必须包含LoginProvider值。

public IActionResult LoginWithTwich(string returnUrl = null)
    {

        var authProperties = _signInManager.ConfigureExternalAuthenticationProperties("Twitch", returnUrl);

        return Challenge(authProperties, "Twitch");
    }

AccountController.cs Handling the Callback AccountController.cs处理回调

Finally when we handle the callback the GetExternalLoginInfoAsync method no longer returns null. 最后,当我们处理回调时,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);
        }
    }

This work for me (version net core 2.2) 为我工作(版本网络核心2.2)

  1. Install the next package: 安装下一个软件包:

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

  1. After register the client keys like user-secrets 注册客户端密钥后,例如用户秘密

dotnet user-secrets set Authentication:Instagram:ClientId YourClientId dotnet用户秘密设置Authentication:Instagram:ClientId YourClientId

dotnet user-secrets set Authentication:Instagram:ClientSecret YourClientSecret dotnet用户秘密设置身份验证:Instagram:ClientSecret YourClientSecret

Finally in startup class: 最后在启动类中:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 GetExternalLoginInfoAsync在ASP.NET Core 2.0中返回null - GetExternalLoginInfoAsync returns null in asp.net core 2.0 OWIN 的 GetExternalLoginInfoAsync 总是返回 null - OWIN's GetExternalLoginInfoAsync Always Returns null AspNet 核心标识 GetExternalLoginInfoAsync 始终为空 - AspNet Core Identity GetExternalLoginInfoAsync Always Null 使用Instagram API在.NET中使用OAuth 2.0 - OAuth 2.0 In .NET With Instagram API 在IAsyncPageFilter-Asp.Net Core 2.0 Razor Pages中的OnPageHandlerExecutionAsync中,PageResult始终返回null - PageResult always returns null in IAsyncPageFilter - OnPageHandlerExecutionAsync in Asp.Net Core 2.0 Razor Pages ASP.NET Facebook 登录 GetExternalLoginInfoAsync 总是返回 Null - ASP.NET Facebook Login GetExternalLoginInfoAsync Always Return Null AuthenticationManager.GetExternalLoginInfoAsync始终为null - AuthenticationManager.GetExternalLoginInfoAsync always null AuthenticationManager.GetExternalLoginInfoAsync() 始终为空 - AuthenticationManager.GetExternalLoginInfoAsync() always null IFormFile 在 dotnet core 2.0 上总是返回 Null 值 - IFormFile always returns Null value on dotnet core 2.0 ASP.NET Core 2.0-配置[“ TestSecret”]始终返回null - ASP.NET Core 2.0 - Configuration[“TestSecret”] always return null
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM