首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >未从IdentityServer4返回到客户端应用程序的TenantId声明

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

Stack Overflow用户
提问于 2018-08-07 23:50:31
回答 1查看 767关注 0票数 0

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

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

代码语言:javascript
复制
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();
        }

交互正在工作,用户在选择租户后被正确地重定向回客户端应用程序。

然而,在我的客户端上,我有一个简单的方法:

代码语言:javascript
复制
<dl>
            @foreach (var claim in User.Claims)
            {
                <dt>@claim.Type</dt>
                <dd>@claim.Value</dd>
            }
        </dl>

来自IdentityServer4的代码片段很快就开始显示声明,不幸的是,我的TenantId声明不在那里。

我已经在我的IdentityServer设置上的客户机的定义中考虑到了它,如下所示:

代码语言:javascript
复制
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()中,如下所示:

代码语言:javascript
复制
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)来请求这个额外的作用域,如下所示:

代码语言:javascript
复制
services.AddAuthentication(options =>
            {
                options.DefaultScheme = "Cookies";
                options.DefaultChallengeScheme = "oidc";
            })
                .AddCookie("Cookies")
                .AddOpenIdConnect("oidc", options =>
                {
                    //other settings not shown

                    options.Scope.Add("TenantId");

                });

而且,所指示的代码片段在客户机上显示的唯一声明是:

编辑2:已修复!

最后,@RichardGowan的答案起作用了。这是因为(正如@AdemCaglin出色地观察到的)我使用的是IdentityServer的AspNetIdentity,它有自己的IProfileService实现,尽管有所有这些其他设置,它仍然放弃了我的自定义TenantId声明)。

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-08-08 16:03:23

您将需要提供并注册一个IProfileService实现,以将您的自定义声明发送回客户端:

代码语言:javascript
复制
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;
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51730868

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档