从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声明,在AllowedScopes
中也没有提及客户定义中的TenantId声明。我的IdSrv,并且在客户端上services.AddAuthentication
的配置中没有提及它。
答案 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;
}
}