ASP核心向Auth Token添加自定义声明

时间:2016-06-27 17:50:01

标签: authentication asp.net-core

我正在使用openiddict和ASP Identity,我正在尝试添加" GroupId"作为对登录时返回的身份验证令牌的声明(使用/ connect / token端点 - 请参阅下面的示例)。 GroupId是我的AplicationUser类中的属性。

我尝试使用IClaimsTransformer,但这看起来很笨重,我无法从ClaimsTransformationContext轻松访问UserManager。

如何在我的IClaimsTransformer中通过DI获取UserManager,或者只将GroupId添加到在connect / token端点生成的令牌?

我按照this示例设置了我的网站。这就是我想做的事情:

var groupGuid = User.Claims.FirstOrDefault(c => c.Type == "GroupGuid");

2 个答案:

答案 0 :(得分:4)

有几种方法可以实现它:
首先,在自定义CreateUserPrincipalAsync中覆盖SignInManager方法:

public override async Task<ClaimsPrincipal> CreateUserPrincipalAsync(ApplicationAdmin user)
{
    var principal = await base.CreateUserPrincipalAsync(user);
    // use this.UserManager if needed
    var identity = (ClaimsIdentity)principal.Identity;
    identity.AddClaim(new Claim("MyClaimType", "MyClaimValue"));            

    return principal;
}

第二种方法是覆盖自定义CreateAsync的<{1}}方法:

UserClaimsPrincipalFactory

基本上是相同的,因为public override async Task<ClaimsPrincipal> CreateAsync(ApplicationUser user) { var principal = await base.CreateAsync(user); var identity = (ClaimsIdentity)principal.Identity; identity.AddClaim(new Claim("MyClaimType", "MyClaimValue")); return principal; } 中的base.CreateUserPrincipalAsync方法会在SignInManager内调用this.UserClaimsPrincipalFactory()

不要忘记将自定义实现添加到服务中:

public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddSignInManager<CustomSignInManager>();
}

public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddScoped<IUserClaimsPrincipalFactory<ApplicationUser>, CustomClaimsPrincipalFactory>();
}

答案 1 :(得分:0)

  

ASP核心向Auth Token添加自定义声明

您在IdP签名后无法更改令牌,因此您无法向令牌添加声明。

  

我尝试过使用IClaimsTransformer,但这看起来很笨重,我   无法从中轻松到达UserManager   ClaimsTransformationContext。

我猜你的问题与这个github issue有关。总而言之(据我所知)如果ClaimsTransformer类被注册为singletion并且其依赖项之一是作用域或瞬态的,则会导致captive dependency。在这种情况下,您应该使用服务定位器模式来避免受限制。你的代码可能是这样的(来自@PinpointTownes的评论):

public async Task<ClaimsPrincipal> TransformAsync(ClaimsTransformationContext context) 
{
    var userManager= context.Context.RequestServices.GetRequiredService<UserManager>();
    //
} 

- 我对您案件的看法 -

您基本上有两种选择来实现目标:

在IdP生成令牌时添加对令牌的声明:

大多数情况下你不需要这种方法,但如果你想使用它:

  • 您应该可以控制IdP,因为IdP上可以使用此选项(据我所知,您的IdP和资源服务器相同,因此您可以控制IdP,但可能始终无法控制)。
  • 使用此选项时应注意不一致,因为声明存储在令牌中并且不会获得每个请求。因此,声明的真实价值可能与令牌中的声明不同。(我不喜欢角色,权限,群组等等,因为这些声明可以随时更改。)

p.s:我不知道是否可以使用Openiddict向令牌添加声明。

声明转换

实际上,在我发现这种方法之前,我使用HttpContext.Items来存储其他声明,这对我来说效果很好。但我认为更好的方法是使用Claims Transformation,它适合您的情况。

相关问题