返回ExternalCallback

时间:2017-10-24 09:01:10

标签: asp.net-core asp.net-identity identityserver4

我正在将两个asp.net核心1.1身份服务器应用程序升级到asp.net核心2。

第一个,IdentityServer A充当联合网关和身份存储。第二个,IdentityServer B使用A作为外部提供者。在我的应用程序域中,客户端应该对B进行身份验证,这会对从A中收到的身份提出额外的声明。

此时认证流程似乎正常,除非B正在向身份添加其他声明。

On A IdentityServer配置如下:

services.AddIdentityServer()
    .AddDeveloperSigningCredential()
    .AddInMemoryClients(Clients.GetClients())
    .AddInMemoryIdentityResources(IdentityResources.GetIdentityResources())
    .AddAspNetIdentity<ApplicationUser>()
    .AddProfileService<ProfileService>();

A上的ProfileService实现如下:

public async Task GetProfileDataAsync(ProfileDataRequestContext context)
{
    var user = await _userManager.GetUserAsync(context.Subject);

    // Scope: OpenId
    AddClaimIfRequested(JwtClaimTypes.Subject, context.RequestedClaimTypes, context.IssuedClaims, user.Id);

    // Scope: Profile
    AddClaimIfRequested(JwtClaimTypes.GivenName, context.RequestedClaimTypes, context.IssuedClaims, user.Firstname);
    AddClaimIfRequested(JwtClaimTypes.FamilyName, context.RequestedClaimTypes, context.IssuedClaims, user.Lastname);
    AddClaimIfRequested(JwtClaimTypes.Picture, context.RequestedClaimTypes, context.IssuedClaims, Convert.ToBase64String(user.ProfilePicture));

    // Scope: Email
    AddClaimIfRequested(JwtClaimTypes.Email, context.RequestedClaimTypes, context.IssuedClaims, user.Email);
}

private void AddClaimIfRequested(string claim, IEnumerable<string> requestedClaims, List<Claim> issuedClaims, string value)
{
    if (requestedClaims.Contains(claim))
        issuedClaims.Add(new Claim(claim, value));
}

在B上,来自A的ExternalCallback在AccountController.ExternalCallback中处理:

public async Task<IActionResult> ExternalCallback(string returnUrl)
{
    //Read external identity from the tempoary cookie
    var result = await HttpContext.AuthenticateAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme);
    if (result == null)
        throw new Exception("External authentication error");

    var externalUser = result.Principal;
    if (externalUser == null)
        throw new Exception("External authentication error");

    //Get external claims
    var claims = externalUser.Claims.ToList();

    ... additional identity handling and signin on B.

此时,索赔中没有任何图片声明。已经在A的ProfileService中设置的其他配置文件相关的声明都存在。如果我在ProfileService中对其他一些声明值进行硬编码,我会按预期看到ExternalCallback中反映的值。但图片声称不存在。此外,当执行GetProfileDataAsync时,context.RequestedClaimTypes确实包含“profile”。

我已经尝试为图片声明提供硬编码值(指向png文件的URL(这似乎是正确的方式)),但没有区别。 由于图片值是base64编码的图像文件,我也尝试增加Kestrel的MaxResponseBufferSize,但这也没有任何区别。

由于在ProfileService中设置了声明值,我猜它必须在调用

之前的某个地方
var result = await HttpContext.AuthenticateAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme);

为什么图片声称不存在我无法弄清楚。欢迎任何建议。

修改 更多信息。在B上,其中定义了.AddOpenIdConnect(“oidc”...),我尝试将onUserInformationReceived事件添加到options.Events。当收到用户信息时,我可以在上下文中看到picture属性作为User对象的一部分。因此,这些信息是可用的,但不会作为声明添加......似乎。

0 个答案:

没有答案