使用映射到多个资源的 URI 执行 Keycloak 策略

问题描述 投票:0回答:1

我正在使用 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-spring-boot-starter
1个回答
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

评估API

{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]"
    }
}

© www.soinside.com 2019 - 2024. All rights reserved.