Instagram OAuth GetExternalLoginInfoAsync在.NET Core 2.0中始终返回null [英] Instagram OAuth GetExternalLoginInfoAsync always returns null in .NET Core 2.0

查看:196
本文介绍了Instagram OAuth GetExternalLoginInfoAsync在.NET Core 2.0中始终返回null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我能够使用此在.NET Core 1中配置Instagram身份验证库,但我似乎无法使其在.NET Core 2中正常工作.

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 2.0兼容的Instagram OAuth库,因此我尝试使用内置的AddOAuth方法.我能够毫无问题地进行所有身份验证,但是由于某种原因,LinkLoginCallback中的GetExternalLoginInfoAsync方法始终返回null.由于所有这些事情都发生在AspNetCore.Authentication中,因此我假设我的设置和配置不正确(或缺少一些关键内容),或者由于其他原因该解决方案无法正常工作.

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. I'm able to get everything to authenticate without a problem, but for some reason my GetExternalLoginInfoAsync method in the LinkLoginCallback always returns 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.

我在ConfigureServices中的配置如下:

My config in ConfigureServices looks like this:

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进行身份验证吗?任何帮助将不胜感激!

Has anybody been able to successfully authenticate with Instagram in .NET Core 2.0? Any help would be greatly appreciated!

推荐答案

不是专门针对Instagram,但我已经使用上述类似的设置为Twitch使用了自定义OAuth验证.

Not specifically for Instagram but I have got custom OAuth validation working for Twitch using a similar setup as above.

我从GetExternalLoginInfoAsync中得到了相同的Null错误,我必须经过许多步骤才能使其工作.

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方法的源代码找到了问题-

In the end I found the problem by looking at the source code for the GetExternalLoginInfoAsync method found here - Microsoft.AspNetCore.Identity.SignInManager.cs

  1. 我发现的第一件事实际上是方法的第一行

  1. The first thing I found is literally on the first line of the method

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

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

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. Leaving SignInScheme set as the default value also didn't seem to work for me.

LoginProviderKey为空.

The LoginProviderKey was null.

if (auth?.Principal == null || items==null||!items.ContainsKey(LoginProviderKey)){return null;}

  • 解决了上述问题后,我发现没有设置索赔,因此我也必须手动设置.我在另一个Stackoverflow问题上找到了一个示例- AddOAuthlinkedin dotnet core 2.0

    请在下面查看我的最终代码:

    Please see below my final code:

    Startup.cs配置OAuth中间件

    在启动中,我将SignInScheme设置为使用IdentityConstants.ExternalScheme值,并在OnCreatingTicket中添加了客户Claims设置事件.

    In the Startup I set the SignInScheme to use the IdentityConstants.ExternalScheme value and added the customer Claims setup event in 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值.

    When we issue the challenge we also have to include the LoginProvider value.

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

    AccountController.cs处理回调

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

    Finally when we handle the callback the GetExternalLoginInfoAsync method no longer returns 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);
            }
        }
    

    这篇关于Instagram OAuth GetExternalLoginInfoAsync在.NET Core 2.0中始终返回null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆