在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");
});而且,所指示的代码片段在客户机上显示的唯一声明是:

编辑2:已修复!
最后,@RichardGowan的答案起作用了。这是因为(正如@AdemCaglin出色地观察到的)我使用的是IdentityServer的AspNetIdentity,它有自己的IProfileService实现,尽管有所有这些其他设置,它仍然放弃了我的自定义TenantId声明)。
最后,我可以撤销所有其他设置……我在GetIdentityResources中没有提到TenantId声明,在我的IdSrv中的客户端定义中没有在AllowedScopes中提到它,在我的客户端上的services.AddAuthentication配置中也没有提到它。
发布于 2018-08-08 16:03:23
您将需要提供并注册一个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;
}
}https://stackoverflow.com/questions/51730868
复制相似问题