如何在ASP.NET Core 3.0 Preview 5中将声明映射选项传递给IdentityServerJwt? [英] How to pass claims mapping options to IdentityServerJwt in ASP.NET Core 3.0 Preview 5?
问题描述
灵感来自有关自定义声明的文章,我向身份服务器"登录过程中添加了一个租户ID自定义声明,如下所示:
Inspired by an article on custom claims, I've added a tenant id custom claim to my Identity server sign in process as follows:
using System;
using System.Security.Claims;
using System.Threading.Tasks;
using MyNamespace.Models;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Options;
using MyNamespace.Data;
using MyNamespace.Constants;
namespace MyNamespace.Factories
{
public class TenantClaimsPrincipalFactory : UserClaimsPrincipalFactory<ApplicationUser>
{
public TenantClaimsPrincipalFactory(
UserManager<ApplicationUser> userManager,
IOptions<IdentityOptions> optionsAccessor)
: base(userManager, optionsAccessor) {
}
// TODO: Remove hard binding to application db context
protected override async Task<ClaimsIdentity> GenerateClaimsAsync(ApplicationUser user) {
var identity = await base.GenerateClaimsAsync(user);
var tenantId = ApplicationDbContext.DefaultTenantId;
if (user.TenantId != Guid.Empty) {
tenantId = user.TenantId;
}
identity.AddClaim(new Claim(CustomClaimTypes.TenantId, tenantId.ToString()));
return identity;
}
}
}
声明生成方法在登录时执行,并将声明添加到身份中,因此这部分看起来还可以.稍后,我尝试在我的租户提供者服务中读取请求,如下所示:
The claims generating method is executed at login and claims are added to the identity, so this part seems ok. Later I try to read out the claim later in my tenant provider service as follows
using System;
using MyNamespace.Data;
using Microsoft.AspNetCore.Http;
using System.Security.Claims;
using System.Linq;
using MyNamespace.Constants;
namespace MyNamespace.Services
{
public interface ITenantProvider
{
Guid GetTenantId();
}
public class TenantProvider : ITenantProvider
{
private IHttpContextAccessor _httpContextAccessor;
public TenantProvider(IHttpContextAccessor httpContextAccessor
{
_httpContextAccessor = httpContextAccessor;
}
// TODO: Remove hard binding to application db context
public Guid GetTenantId()
{
var userId = _httpContextAccessor.HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value;
var user = _httpContextAccessor.HttpContext.User;
var tenantId = _httpContextAccessor.HttpContext.User.FindFirst(CustomClaimTypes.TenantId).Value;
Guid tenantGuid = ApplicationDbContext.DefaultTenantId;
Guid.TryParse(tenantId, out tenantGuid);
return tenantGuid;
}
}
}
据我了解,CustomClaimTypes.TenantId
标识的声明为
As far as I understand, however, the claim identified by CustomClaimTypes.TenantId
is not automatically mapped by the Identity server. My question is this: how can I map
options.ClaimActions.MapUniqueJsonKey(CustomClaimTypes.TenantId, CustomClaimTypes.TenantId);
从Startup.cs
在我将身份服务器添加到我的依赖项的地方:
from Startup.cs
where I add the Identity server the my dependencies:
services.AddAuthentication()
.AddIdentityServerJwt();
推荐答案
因此,最终我得到了与最初寻求的解决方案不同的解决方案.而不是映射工厂创建的声明,我遇到了
So, in the end I ended up with a different solution than what I sought originally. Instead of mapping the claims as created by the factory, I came across another post here at StackOverflow. Basically, what I did was the following. I implemented the following ProfileService
namespace MyNamespace.Services
{
public class ProfileService : IProfileService
{
protected UserManager<ApplicationUser> _userManager;
public ProfileService(UserManager<ApplicationUser> userManager)
{
_userManager = userManager;
}
public async Task GetProfileDataAsync(ProfileDataRequestContext context)
{
var user = await _userManager.GetUserAsync(context.Subject);
var claims = new List<Claim>
{
new Claim(CustomClaimTypes.TenantId, user.TenantId.ToString()),
};
context.IssuedClaims.AddRange(claims);
}
public async Task IsActiveAsync(IsActiveContext context)
{
var user = await _userManager.GetUserAsync(context.Subject);
context.IsActive = (user != null) && user.IsActive;
}
}
}
然后,我在Configure
的DI容器中添加了该服务:
Then, I added the service in the DI Container at Configure
:
services.AddIdentityServer()
.AddApiAuthorization<ApplicationUser, ApplicationDbContext>()
.AddProfileService<ProfileService>();
services.AddAuthentication()
.AddIdentityServerJwt();
因此,我仍然很高兴让AddIdentityServerJwt
设置IdentityServer4,同时获得我的主张.
So, I still have a good time letting AddIdentityServerJwt
setting up IdentityServer4, while getting my claims at the same time.
这篇关于如何在ASP.NET Core 3.0 Preview 5中将声明映射选项传递给IdentityServerJwt?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!