TenantId声明未从IdentityServer4返回到客户端应用

时间:2018-08-07 15:50:31

标签: authentication identityserver4

this问题开始,我最终在用户选择租户之后,使用HttpContext.SignInAsync(string subject, Claim[] claims)重载将所选的租户ID作为声明(定义为类型“ TenantId”)作为声明传递。

然后,我在this问题的自定义AccountChooserResponseGenerator类中检查此声明,以确定是否需要将用户定向到“租户选择器”页面,如下所示:

public override async Task<InteractionResponse> ProcessInteractionAsync(ValidatedAuthorizeRequest request, ConsentResponse consent = null)
        {
            var response = await base.ProcessInteractionAsync(request, consent);
            if (response.IsConsent || response.IsLogin || response.IsError)
                return response;

            if (!request.Subject.HasClaim(c=> c.Type == "TenantId" && c.Value != "0"))
                return new InteractionResponse
                {
                    RedirectUrl = "/Tenant"
                };

            return new InteractionResponse();
        }

交互正在进行,选择租户后,用户可以正确重定向到客户端应用。

但是,在我的客户端上,我很简单:

<dl>
            @foreach (var claim in User.Claims)
            {
                <dt>@claim.Type</dt>
                <dd>@claim.Value</dd>
            }
        </dl>
IdentityServer4快速入门中的

片段显示了声明,可悲的是,我的TenantId声明不存在。

在我的IdentityServer设置上的“客户端”定义中,已允许这样做,如下所示:

var client = new Client
                {
... other settings here
                    AllowedScopes = new List<string>
                    {
                        IdentityServerConstants.StandardScopes.OpenId,
                        IdentityServerConstants.StandardScopes.Profile,
                        IdentityServerConstants.StandardScopes.Email,
                        IdentityServerConstants.StandardScopes.Phone,
                        "TenantId"
                    }
                };

要使TenantId声明在我的客户端应用程序中可见,我需要缺少什么?

编辑:

基于@d_f的评论,我现在将TentantId添加到服务器的GetIdentityResources()中,如下所示:

public static IEnumerable<IdentityResource> GetIdentityResources()
        {
            return new List<IdentityResource>
            {
                new IdentityResources.OpenId(),
                new IdentityResources.Profile(),
                new IdentityResources.Email(),
                new IdentityResources.Phone(),
                new IdentityResource("TenantId", new[] {"TenantId"})
            };
        }

我已经编辑了客户的startup.ConfigureServices(IServiceCollection services),以请求此附加范围,如下所示:

services.AddAuthentication(options =>
            {
                options.DefaultScheme = "Cookies";
                options.DefaultChallengeScheme = "oidc";
            })
                .AddCookie("Cookies")
                .AddOpenIdConnect("oidc", options =>
                {
                    //other settings not shown

                    options.Scope.Add("TenantId");

                });

并且仍然仅在客户端上显示所指示片段的声明是: claims

编辑2:已修复!

最后,@ RichardGowan的答案奏效了。这是因为(如@AdemCaglin所观察到的那样),我使用的是IdentityServer的AspNetIdentity,它具有IProfileService的自己的实现,尽管具有所有其他设置,但它仍然删除了我的自定义TenantId声明)。

最后,我可以撤消所有其他设置...在GetIdentityResources中我没有提到TenantId声明,在AllowedScopes中也没有提及客户定义中的TenantId声明。我的IdSrv,并且在客户端上services.AddAuthentication的配置中没有提及它。

1 个答案:

答案 0 :(得分:0)

您将需要提供并注册IProfileService的实现,才能向您的客户发出自定义声明:

public class MyProfileService : IProfileService {
    public MyProfileService() {
    }

    public Task GetProfileDataAsync(ProfileDataRequestContext context) {
        // Issue custom claim
        context.IssuedClaims.Add(context.Subject.Claims.First(c => c.Type == 
               "TenantId"));
        return Task.CompletedTask;
    }

    public Task IsActiveAsync(IsActiveContext context) {
        context.IsActive = true;
        return Task.CompletedTask;
    }
}