每个用户的 Keycloak 硬编码声明

Keycloak harcoded claim for each user

我用的是微服务架构。每个服务都使用承载访问类型。 用户通过 public 服务获得令牌。 每项服务都是具有自己特权的业务应用程序。 Rabbit mq 用作进程间通信。 Keycloak 通过 JWT 为每个服务转移用户角色。 但是我想在用户的令牌中转移用户权限。

像这样:

priveleges:[
 {resource: subjects,
  roles:[ADMIN,OPER,COMPLAINCE],
  categories:[
    read:[1,2,3,4,5],
    write:[3,4,5],
    delete:[3,4,5] 
  ],
  notes:[
    read:[1,2,3,4,5],
    write:[3,4,5],
    delete:[3,4,5]  
  ],
  subject:[
    read:true,
    write:true,
    delete:false
  ],
  addresses:[
    read:true,
    write:true,
    delete:false
  ]
 },


 {resource: cards,
  roles:[ADMIN,OPER,COMPLAINCE],
  card:[
    read:true,
    write:true,
    delete:false
  ],
  fin-operation:[1,2,3,4,5],
  non-fin-operation:[1,2,3,4]
 }
]

我有两个问题:

  1. 我可以在keycloak中为每个用户设置不同的权限吗? 我知道可以在 Keycloak 中使用带有硬编码映射器类型的 ProtocolMapper。在这种情况下,它将是所有用户的一个,但我需要为每个用户声明特权。

  2. 在token中传递权限是否正确,以便以后在后端和前端进行处理?

附加信息: 但是,如果我尝试添加超过 255 个字符的字符串值,我会发现错误,因为它是 it 字段的约束。 我在日志 jboss 中有错误: 错误:对于类型字符 varying(255)

来说值太长

我尝试添加此声明:

{ "priveleges":[ { "resource":"subjects", "roles":[ "ADMIN", "OPER", "COMPLAINCE" ], "categories":[ { "read":[ 1, 2, 3, 8, 5 ] }, { "write":[ 3, 9, 5 ] }, { "delete":[ 3, 6, 5 ] } ], "notes":[ { "read":[ 1, 2, 3, 7, 5 ] }, { "write":[ 3, 4, 5 ] }, { "delete":[ 3, 4, 5 ] } ] }, { "resource":"cards", "roles":[ "ADMIN", "OPER", "COMPLAINCE" ], "fin-operation":[ 1, 2, 3, 4, 5 ], "non-fin-operation":[ 1, 2, 3, 4 ] } ] }

Can I set different privileges for each user in keycloak? I know it is possible to use a ProtocolMapper with a hardcoded mapper type in Keycloak. And in this case it will be one for all users but I need to have privelegies claim for each user.

如果我正确理解你所说的“特权”是什么意思,你至少可以通过以下两种方式实现它:1)相应地创建并分配Realm roles给用户,并创建自定义user attribute 在您的每个用户上。或者,您可以使用 Keycloak Authorization features 来处理它,但这需要一些工作。

Is it correct to pass privileges in a token, so that later they can be processed on the backend and frontend?

是的,通常使用 Keycloak 进行身份验证,并使用后端根据在代表某些用户请求的令牌上注入的角色来执行授权部分。

让我为您提供一个说明性示例。首先通过以下方式创建领域角色:

  • 你的领域;
  • Select 角色;
  • 添加角色;
  • 例如,现在为 ADMIN、OPER 和 COMPLAINCE 创建一个单独的角色;
  • 保存这些角色;

现在让我们将 Realm Roles 分配给用户并创建一个 User Attribute,方法是:

  • 你的领域;

  • 用户;

  • 点击一个用户;

  • 将选项卡切换到角色映射;

  • Select要分配给用户的Realm Roles,点击Add selected

  • 现在转到属性;

  • 将其余声明添加到用户中。例如,Key = "priveleges" 和 value = {"resource": "subjects","categories": [{"read": [1,2,3,8,5]},{"write": [3,9,5]},{"delete": [3,6,5]}],"notes": [{"read": [1,2,3,7,5]},{"write": [3,4,5]},{"delete": [3,4,5]}]}.

最后,您需要创建一个 Mapper 来将新创建的 user attribute 映射到令牌中。为此,请访问:

  • 你的领域;
  • 客户;
  • Select 您的客户;
  • 映射器;
  • 创建;
  • 填写字段,即
    • Name:“权限”
    • As Mapper Type select "用户属性";
    • User Attribute:特权;
    • Token Claim Name:特权;
    • Claim JSON Type : JSON;
    • 相应地填写其余部分。
    • 点击保存。

现在代表用户向您的客户端请求令牌。解码后的令牌将如下所示:

 "iat": ......,
  "jti": "......",
  "iss":  "......",
  "aud":  "......",
  "sub":  "......",
  "typ":  "......",
  "azp":  "......",
  "session_state":  "......",
  "acr": "1",
  "allowed-origins": [
    "http://localhost:8080"
  ],
  "realm_access": {
    "roles": [
      "COMPLAINCE",
      "offline_access",
      "uma_authorization",
      "ADMIN",
      "OPER",
      "app-user"
    ]
  },
  "resource_access": {
    "springboot-microservice": {
      "roles": [
        "user"
      ]
    },
    "account": {
      "roles": [
        "manage-account",
        "manage-account-links",
        "view-profile"
      ]
    }
  },
  "scope": "profile email",
  "email_verified": true,
  "priveleges": {
      "resource": "subjects",
      "categories": [
        {
          "read": [
            1,
            2,
            3,
            8,
            5
          ]
        },
        {
          "write": [
            3,
            9,
            5
          ]
        },
        {
          "delete": [
            3,
            6,
            5
          ]
        }
      ],
      "notes": [
        {
          "read": [
            1,
            2,
            3,
            7,
            5
          ]
        },
        {
          "write": [
            3,
            4,
            5
          ]
        },
        {
          "delete": [
            3,
            4,
            5
          ]
        }
      ]
   },
  "name": "e 1",
  "preferred_username": "employee1",
  "given_name": "e",
  "family_name": "1",
}

声明中的角色:

 "realm_access": {
    "roles": [
      "COMPLAINCE",
      "offline_access",
      "uma_authorization",
      "ADMIN",
      "OPER",
      "app-user"
    ]

但是,如果您希望领域角色也在 priveleges 声明下,您需要将它们添加到我们之前创建的 user attribute 声明中。

但是请记住,每个每个用户属性可以保存多少个字符是有限制的(255 个字符)。因此,您可能必须将声明拆分为多个声明( 用户属性)。