首页 > 解决方案 > 在不同软件中使用 IdentityServer 登录后设置声明

问题描述

我有两个软件,想集成到一个identityserver. 两者都是软件是多租户的,使用共享数据库

所有表都有一个名为 TenantId 的列,并且在我的DbContext(EF Core)中我 filter Where(x => x.TenantId == TenantId)。目前我将此 TenantId 存储在声明中,并使用一个简单的解决方案来生成 JWT

在谷歌搜索中,我看到在 access_token 中添加声明的一种方法是通过ProfileService,但我的问题是,在每个软件中,用户可能有不同的 TenantId

这个问题中,他们OnTokenValidated用来添加新的声明

但我想知道,谁返回软件的 access_token?API 或 IdentityServer,因为在这种情况下,您需要成为 API 才能添加新的声明

总结:我只想identityserver登录和生成token,授权等逻辑会直接在各个软件里面

标签: asp.netasp.net-coreidentityserver4

解决方案


在您添加的链接中,您可以看到 access_token 实际上没有被修改。发生的情况是来自 access_token 的声明被映射到 User.Identity。并在OnTokenValidated附加声明中添加到此 User.Identity。

问题是租户 ID 不适合作为声明,因为 IdentityClaims 应该对独立于上下文的身份进行建模,而租户 ID 的某些内容是上下文相关的。

对于你不能使用的资源OnTokenValidated。而是使用中间件。我建议您看一下 IdentityServer 团队的解决方案:PolicyServer

简而言之,在身份验证 (IdentityServer) 之后,策略服务器根据配置的授权向 User.Identity 添加声明。

API 中有两部分(=resource):

  1. 使用授权声明扩展 User.Identity
  2. 政策,因为这是逻辑应该发生的地方。

然后你就会得到你想要的。基于资源的授权。

PolicyServer 使用 json 设置文件,但您可以使用自己的存储扩展它。该示例缺少正常声明,但您可以使用声明扩展 Policy 模型:

// Just the lines to include claims.
public class Policy
{
    public List<Claim> Claims { get; internal set; } = new List<Claim>();

    internal Task<PolicyResult> EvaluateAsync(ClaimsPrincipal user)
    {
        var claims = Claims.Select(x => new Claim { Name = x.Name, Value = x.Value }).ToArray();

        var result = new PolicyResult()
        {
            Claims = claims
        };
    }
}

在配置中:

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

在中间件中将声明添加到 User.Identity,例如:

id.AddClaims(claims);

推荐阅读