AddOAuth linkedin dotnet core 2.0

jac*_*per 8 c# oauth asp.net-core-mvc .net-core .net-core-2.0

我正在使用dotnet核心我想在网站上设置LinkedIn身份验证,因为LinkedIn没有默认身份验证构建器,因为facebook,google和twitter我决定使用如下通用实现:

services.AddAuthentication().AddOAuth("LinkedIn", 
            c =>
            {
                c.ClientId = Configuration["linkedin-app-id"];
                c.ClientSecret = Configuration["linkedin-app-secret"];
                c.Scope.Add("r_basicprofile");
                c.Scope.Add("r_emailaddress");
                c.CallbackPath = "/signin-linkedin";
                c.AuthorizationEndpoint = "https://www.linkedin.com/oauth/v2/authorization";
                c.TokenEndpoint = "https://www.linkedin.com/oauth/v2/accessToken";
                c.UserInformationEndpoint = "https://api.linkedin.com/v1/people/~:(id,formatted-name,email-address,picture-url)";
})
Run Code Online (Sandbox Code Playgroud)

我有一个问题,因为GetExternalLoginInfoAsync()为null,查看Identity ASP.net核心源,是因为providerkey为null.

摘自asp.net核心代码:

var providerKey = auth.Principal.FindFirstValue(ClaimTypes.NameIdentifier);
var provider = items["LoginProvider"] as string;
if (providerKey == null || provider == null)
{
   return null;
}
Run Code Online (Sandbox Code Playgroud)

问题是我在哪里可以将ClaimTypes.NameIdentifier添加到LinkedIn声明?

jac*_*per 16

在这种情况下,您必须使用OauthEvent手动预填充每个Claim,如下所示:

.AddOAuth("LinkedIn", 
            c =>
            {
                c.ClientId = Configuration["linkedin-app-id"];
                c.ClientSecret = Configuration["linkedin-app-secret"];
                c.Scope.Add("r_basicprofile");
                c.Scope.Add("r_emailaddress");
                c.CallbackPath = "/signin-linkedin";
                c.AuthorizationEndpoint = "https://www.linkedin.com/oauth/v2/authorization";
                c.TokenEndpoint = "https://www.linkedin.com/oauth/v2/accessToken";
                c.UserInformationEndpoint = "https://api.linkedin.com/v1/people/~:(id,formatted-name,email-address,picture-url)";
                c.Events = new 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 userId = user.Value<string>("id");
                        if (!string.IsNullOrEmpty(userId))
                        {
                            context.Identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, userId, ClaimValueTypes.String, context.Options.ClaimsIssuer));
                        }

                        var formattedName = user.Value<string>("formattedName");
                        if (!string.IsNullOrEmpty(formattedName))
                        {
                            context.Identity.AddClaim(new Claim(ClaimTypes.Name, formattedName, ClaimValueTypes.String, context.Options.ClaimsIssuer));
                        }

                        var email = user.Value<string>("emailAddress");
                        if (!string.IsNullOrEmpty(email))
                        {
                            context.Identity.AddClaim(new Claim(ClaimTypes.Email, email, ClaimValueTypes.String,
                                context.Options.ClaimsIssuer));
                        }
                        var pictureUrl = user.Value<string>("pictureUrl");
                        if (!string.IsNullOrEmpty(pictureUrl))
                        {
                            context.Identity.AddClaim(new Claim("profile-picture", pictureUrl, ClaimValueTypes.String,
                                context.Options.ClaimsIssuer));
                        }
                    }
                };

            })
Run Code Online (Sandbox Code Playgroud)