在启动时从存储在数据库中添加自定义声明

时间:2020-02-03 22:42:31

标签: c# asp.net-core

我有以下ClaimsTransformer类,在启动时分配自定义声明非常有效,但是我还需要能够检索存储在数据库中的声明并将它们添加到用户身份中。不幸的是,我还没有找到从此类中访问数据库的方法。我的假设是我可以使用DI注入数据库类,但是我无法这样做,因为它不再容纳IClaimsTransformation的构造函数。

public class ClaimsTransformer : IClaimsTransformation
{
    public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
    {
        var identity = principal.Identity as ClaimsIdentity;

        var claims = new List<Claim>();

        using (var context = new PrincipalContext(ContextType.Domain))
        {
            if (identity != null)
            {
                var user = UserPrincipal.FindByIdentity(context, identity.Name);
                if (user != null) claims.Add(new Claim(CustomClaimType.DisplayName.ToString(), user.DisplayName));
            }
        }

        claims.AddRange(identity?.Claims);

        //var newIdentity = new ClaimsIdentity(claims, identity?.AuthenticationType);
        var newIdentity = new ClaimsIdentity(claims, "Kerberos");
        return Task.FromResult(new ClaimsPrincipal(newIdentity));
    }
}

1 个答案:

答案 0 :(得分:0)

您可以看一下PolicyServer的代码以获取一些启发。来自code

// this sets up the PolicyServer client library and policy provider -
// configuration is loaded from appsettings.json
services.AddPolicyServerClient(Configuration.GetSection("Policy"))
    .AddAuthorizationPermissionPolicies();

从json文件读取策略,例如:

"Policy": {
  "claims": [
    {
      "name": "tenantid",
      "value": "44"
    }
  ],
  "roles": [

但是可以是任何来源。在您的情况下,它可能是数据库中填充的一个单例。

并使用middleware添加声明。在您的情况下,例如:

// Inject the repository
public async Task Invoke(HttpContext context, IClaimsRepository repository)
{
    if (context.User.Identity.IsAuthenticated)
    {
        // Get claims from (cached) database, singleton.
        var claims = await repository.GetClaimsAsync();
        if (claims.Count > 0)
        {
            var id = new ClaimsIdentity(claims, "MyMiddleware", "name", "role");
            // Add as extra Identity to User.
            context.User.AddIdentity(id);
        }
    }
    await _next(context);
}