Authentication ASP核心将自定义声明添加到身份验证令牌
我正在使用openiddict和ASP Identity,并尝试添加一个“GroupId”作为登录时返回的身份验证令牌的声明(使用/connect/token端点-请参见下面的示例)。GroupId是我的AplicationUser类中的一个属性 我曾尝试使用Authentication ASP核心将自定义声明添加到身份验证令牌,authentication,asp.net-core,Authentication,Asp.net Core,我正在使用openiddict和ASP Identity,并尝试添加一个“GroupId”作为登录时返回的身份验证令牌的声明(使用/connect/token端点-请参见下面的示例)。GroupId是我的AplicationUser类中的一个属性 我曾尝试使用iclaimsstransformer,但这似乎很笨拙,我无法从ClaimsTransformationContext轻松访问UserManager 我如何通过我的iclaimsstransformer中的DI获取UserManager,或
iclaimsstransformer
,但这似乎很笨拙,我无法从ClaimsTransformationContext轻松访问UserManager
我如何通过我的iclaimsstransformer
中的DI获取UserManager,或者只是将GroupId添加到在connect/token端点生成的令牌中
我按照这个例子建立了我的网站。这就是我想做的:
var groupGuid = User.Claims.FirstOrDefault(c => c.Type == "GroupGuid");
ASP核心将自定义声明添加到身份验证令牌
在IdP对令牌进行签名后,您不能更改令牌,因此您不能向令牌添加声明
我试过使用IClaimsTransformer,但它似乎很笨重,我
无法轻松地从服务器访问UserManager
索赔信息上下文
我想你的问题和这个github有关。总之(据我所知),若claimtransformer
类注册为singletion,并且它的一个依赖项是作用域的或暂时的,那个么它会导致。在这种情况下,您应该使用服务定位器模式来避免捕获依赖。您的代码可能如下所示(来自@PinpointTownes的评论):
public async Task TransformAsync(claimtransformationcontext)
{
var userManager=context.context.RequestServices.GetRequiredService();
//
}
--我对你的案子的看法--
你基本上有两种选择来实现你的目标:
当IdP生成令牌时,向令牌添加声明:
在大多数情况下,您不需要此方法,但如果您想使用它:
- 您应该可以控制IdP,因为此选项在IdP上是可行的(据我所知,您的IdP和资源服务器是相同的,因此您可以控制IdP,但可能并不总是可行的)
- 使用此选项时,您应该注意不一致性,因为声明存储在令牌中,并且不会获得每个请求。因此,声明的实际价值可能不同于令牌中的声明(我不喜欢角色、权限、组等,因为这些声明可以随时更改)
事实上,在我发现这个方法之前,我使用了
HttpContext.Items
来存储额外的声明,它对我很有效。但我认为更好的方法是使用声明转换
,它适合您的情况 有两种方法可以实现它:首先,在自定义
SignInManager
中重写CreateUserPrincipalSync
方法:
public override异步任务CreateUserPrincipalAsync(ApplicationAdmin用户)
{
var principal=await base.CreateUserPrincipalAsync(用户);
//如果需要,请使用this.UserManager
var identity=(ClaimsIdentity)principal.identity;
identity.AddClaim(新索赔(“MyClaimType”、“MyClaimValue”);
返还本金;
}
第二种方法是重写自定义UserClaimsPrincipalFactory
的CreateAsync
方法:
public override async Task CreateAsync(ApplicationUser用户)
{
var principal=await base.CreateAsync(用户);
var identity=(ClaimsIdentity)principal.identity;
identity.AddClaim(新索赔(“MyClaimType”、“MyClaimValue”);
返还本金;
}
这基本上是一样的,因为SignInManager
中的base.createUserPrincipalSync
方法调用this.UserClaimsPrincipalFactory()
内部
不要忘记将自定义实现添加到服务中:或者
public void配置服务(IServiceCollection服务)
{
...
services.AddSignInManager();
}
或
public void配置服务(IServiceCollection服务)
{
...
services.addScope();
}
public async Task<ClaimsPrincipal> TransformAsync(ClaimsTransformationContext context)
{
var userManager= context.Context.RequestServices.GetRequiredService<UserManager>();
//
}