我正在使用 Keycloak (21.0.0) 来管理我的 Spring Boot (2.7.10) 应用程序的授权。
我配置了一些只能由某些用户访问的资源。
这太棒了!
现在我想允许管理员访问所有资源。
这是我的 Keycloak 配置的概述。
** Authorization - Settings **
Decision strategy: Affirmative
**Authorization - Resources**
name: all comments
URIs: /api/comments/*
Authorization scopes: GET
name: first comment
URIs: /api/comments/1
Authorization scopes: GET
**Authorization - Scopes**
name: GET
**Authorization - Policies**
[role policy]
Name: admin
Roles: admin
[user policy]
Name: fubar
Users: fubar
**Authorization - Permissions**
[Scope based]
Name: admin_can_read_all_comments
Resources: all comments
Authorization scopes: GET
Policies: admin
[Scope based]
Name: fubar_can_read_first_comment
Resources: first comments
Authorization scopes: GET
Policies: fubar
当我在 Keycloak Web 客户端中评估 Fubar 时,all_comments 资源评估为 DENY,first_comment 资源评估为 PERMIT。当我在 Keycloak Web 客户端中评估 admin 时,all_comments 资源评估为 PERMIT,first_comment 资源评估为 DENY。
我希望 fubar 和 admin 都可以 GET /api/comments/1
但实际上,当管理员尝试 GET /api/comments/1 时,他得到的是 403
这种行为是预期的吗?
我猜测这种行为与 keycloak-policy-enforcer 的实现有关。当 URI 映射到具有不同结果的多个资源时,策略执行者会做什么?
这是我的 Spring Boot 配置:
keycloak:
securityConstraints:
- authRoles:
- "*"
securityConstraints[0]:
securityCollections[0]:
patterns[0]: /*
principal-attribute: preferred_username
auth-server-url: http://kc-host:8080/auth
realm: my-realm
resource: my-authz-client
bearer-only: true
credentials:
secret: s3cr3t
policy-enforcer-config:
http-method-as-scope: true
lazy-load-paths: true
enforcement-mode: enforcing
path-cache-config:
lifespan: 0
在 Keycloak 中,评估用户对资源的访问通常涉及使用 Keycloak 授权服务中定义的策略和权限。
您需要在Keycloak中启用并配置授权服务。 这涉及设置策略、权限、资源和范围。
Resources
:您想要保护的内容,例如 API、网页或任何其他资源。这是API的目标。
Scopes
:它是对资源执行的操作,例如读取、写入、删除。
Permission
:资源和范围之间的关联。它决定允许或不允许访问资源。
Policy
:定义授予资源访问权限的条件。
那么 “fubar”用户被分配“fubar”角色。 “admin”用户被分配“admin”角色。
“fubar 策略”有两个角色,admin 角色和 fubar 角色。 “管理策略”只有一个角色,只有管理员角色。
“fubar权限”有fubar政策和第一条评论资源。 “管理员权限”拥有管理员策略和所有评论资源。
评估场景 1、2、3、4 案例
案例1:管理员用户访问所有评论资源
案例2:管理员用户访问第1条评论资源
案例3:管理员用户访问所有评论资源
案例4:管理员用户访问第1条评论资源
见下图。 (为什么)
案例1:所有评论资源均具有管理策略 管理策略具有管理员角色,管理角色具有管理员用户。 因此,管理员用户可以访问所有资源。
案例2:第一个评论资源有第一个权限的fubar政策 fubar 策略具有管理员角色,管理员角色具有管理员用户。 因此,管理员用户可以访问第一个资源。
情况3:所有评论资源都有所有权限的管理策略 管理策略具有管理员角色,管理角色具有管理员用户。 所以,fubar 用户无法访问所有资源。
案例 4:第一个评论资源具有第一个权限的 fubar 政策 fubar 策略有 fubar 角色,fubar 角色有 fubar 用户。 因此,fubar 用户可以访问第一个资源。
如果“admin”用户正在访问这两个资源,尽管仅分配了“admin”角色
这个
fubar_policy
可以做到
为 my-client
admin 和 my-client
fubar 角色 分配角色
此
admin_policy
仅为my-client
管理员角色分配角色
管理员允许这两种资源
fubar 只允许
first_comment
{Keycloak URL}/admin/realms/my-realm/clients/{cileint id}/authz/resource-server/policy/evaluate
有效负载
{
"roleIds": [],
"userId": "{user uuid}",
"resources": [
{
"name": "first_comment",
"owner": {
"id": "{client id}",
"name": "{client name}"
},
"ownerManagedAccess": false,
"displayName": "{display resource name}",
"attributes": {},
"_id": "{resource id}",
"uris": ["/api/comments/1"],
"scopes": [
{
"id": "{scope id}",
"name": "GET",
"iconUri": ""
}
],
"icon_uri": ""
}
],
"entitlements": false,
"context": { "attributes": {} }
}
响应示例
{
"results": [
{
"resource": {
"name": "first_comment with scopes [GET]",
"_id": "d8d416f3-c4eb-4157-a038-2828f279ae90"
},
"scopes": [
{
"id": "97406598-494a-47c4-bcdb-ff763d18717a",
"name": "GET"
}
],
"policies": [
{
"policy": {
"id": "33b2fe31-293f-4029-8e7d-25d4dd15f853",
"name": "fubar_can_read_first_comment",
"description": "",
"type": "scope",
"resources": [
"first_comment"
],
"scopes": [
"GET"
],
"logic": "POSITIVE",
"decisionStrategy": "AFFIRMATIVE",
"config": {}
},
"status": "PERMIT",
"associatedPolicies": [
{
"policy": {
"id": "90413ad9-6db7-49fa-889f-c408d3f6db63",
"name": "fubar_policy",
"description": "",
"type": "role",
"resources": [],
"scopes": [],
"logic": "POSITIVE",
"decisionStrategy": "UNANIMOUS",
"config": {}
},
"status": "PERMIT",
"associatedPolicies": [],
"scopes": []
}
],
"scopes": []
}
],
"status": "PERMIT",
"allowedScopes": [
{
"id": "97406598-494a-47c4-bcdb-ff763d18717a",
"name": "GET"
}
]
}
],
"entitlements": false,
"status": "PERMIT",
"rpt": {
"exp": 1710303168,
"iat": 1710302868,
"jti": "5c9dd6b4-2adc-42e4-bf91-00268a25a369",
"aud": "my-client",
"sub": "fe955869-c533-4433-b947-e9d91f00217a",
"typ": "Bearer",
"azp": "my-client",
"session_state": "31e60b44-3c4b-4b6c-b06c-c8d215040ec3",
"acr": "1",
"allowed-origins": [
"http://localhost:8180/api/*"
],
"realm_access": {
"roles": [
"offline_access",
"uma_authorization",
"default-roles-my-realm"
]
},
"resource_access": {
"my-client": {
"roles": [
"fubar"
]
},
"account": {
"roles": [
"manage-account",
"manage-account-links",
"view-profile"
]
}
},
"authorization": {
"permissions": [
{
"scopes": [
"GET"
],
"rsid": "d8d416f3-c4eb-4157-a038-2828f279ae90",
"rsname": "first_comment"
}
]
},
"scope": "email profile",
"sid": "31e60b44-3c4b-4b6c-b06c-c8d215040ec3",
"email_verified": true,
"preferred_username": "fubar",
"email": "[email protected]"
}
}