代码之家  ›  专栏  ›  技术社区  ›  Shawn de Wet

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

  •  0
  • Shawn de Wet  · 技术社区  · 8 年前

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

    然后在我的海关检查这个索赔 AccountChooserResponseGenerator 上课时间 this 确定是否需要将用户定向到租户选择器页的问题,如下所示:

    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 quickstarts中的片段来显示声明,不幸的是,我的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的评论,我现在在服务器的 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:修正!

    最后,理查德戈万的回答奏效了。这是因为(正如@AdemCaglin出色地观察到的那样),我使用的是IdentityServer的AspNetIdentity,它有自己的实现 IProfileService ,尽管进行了其他设置,但仍不断删除我的自定义TenantId声明)。

    所以最后,我可以撤销所有其他设置…我没有提到 GetIdentityResources ,没有提到 AllowedScopes 在我的IdSrv中定义客户机,而在配置 services.AddAuthentication 我的委托人。

    1 回复  |  直到 8 年前
        1
  •  0
  •   Richard    8 年前

    您需要提供并注册 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;
        }
    }