[英]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
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设置为默认值似乎对我也不起作用。
The LoginProviderKey was null. LoginProviderKey为空。
if (auth?.Principal == null || items==null||!items.ContainsKey(LoginProviderKey)){return null;}
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)
Install-Package AspNet.Security.OAuth.Instagram -Version 2.0.1 安装包AspNet.Security.OAuth.Instagram-版本2.0.1
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.