如何解决keycloak 中的资源、范围、权限和策略
我知道我迟到了 2 年多,但我想我会分享我所知道的,并希望为未来的读者减轻一些痛苦。完全透明——我绝不是 Keycloak/OAuth/OIDC 专家,我所知道的主要来自阅读文档、书籍、优秀的 YouTube 和使用该工具。
这篇文章将由两部分组成:
- 我会尽我所能回答你所有的问题
- 我将向您展示如何在 Keycloak 中使用策略/范围/权限,而无需部署单独的应用程序,以便更好地理解此线程中的一些核心概念。请注意,这主要是为了让您开始。我正在使用
Keycloak 8.0.0
.
第一部分
开始之前的一些术语:
- 在 Keycloak 中,您可以创建 2 种类型的权限:基于资源的和基于范围的。
- 简而言之,对于
Resource-Based
权限,您将其直接应用于您的资源 - 为了
Scoped-Based
获得许可,您将其应用于您的范围或范围 资源。
最好的做法是只创建一个“视图”范围,并在多个资源(帐户、事务等)中使用它?或者我应该创建一个“viewAccount”范围、一个“viewTransaction”范围等?
范围表示受保护资源的一组权限。在您的情况下,您有 2 个资源:account
和transaction
,所以我倾向于第二种方法。
从长远来看,拥有view
与所有资源(例如account
、transaction
、customer
…settlement
)相关联的全局范围会使授权难以管理和适应安全需求更改。
以下是一些示例,您可以查看这些示例以了解设计
但请注意 -
我并不是说您不应该跨资源共享范围。事实上,Keycloak
允许这对于具有相同的资源type
。例如,您可能需要同时需要viewAccount
和viewTransaction
范围来读取给定帐户下的交易(毕竟您可能需要访问该帐户才能查看交易)。您的要求和标准将严重影响您的设计。
对于资源和范围的每个实际组合,通常的做法是创建权限吗?
抱歉,我不完全理解这个问题,所以我会有点宽泛。为了授予/拒绝访问 a resource
,您需要:
使政策执行生效。请参阅授权流程。
如何设置这一切完全取决于您。例如,您可以:
-
定义单独的策略,并在适当的权限下绑定每个策略。
-
更好的是,定义单个策略,然后将所有相关策略分组到一个
aggregated
策略(策略策略)下,然后将该聚合策略与scope-based
权限相关联。您可以将该scoped-based
权限同时应用于资源及其所有关联范围。 -
或者,您可以通过利用这两种不同的类型来进一步分解您的权限。您可以通过权限类型单独为您的资源创建权限
resource-based
,并通过权限类型单独将其他权限与范围单独关联scope-based
。
你有选择。
如果有多个权限匹配给定的资源/范围,Keycloak 会做什么?
这取决于
- 资源服务器的
Decision Strategy
- 每个权限的
Decision Strategy
- 每项政策的
Logic
价值。
该Logic
值与 Java
的!
运算符类似。它可以是Positive
或Negative
。当Logic
为Positive
时,策略的最终评估保持不变。当它Negative
的
,最终结果被否定(例如,如果一个策略评估为 false
并且它Logic
是Negative
,那么它将是true
)。为简单起见,我们假设Logic
始终设置为Positive
。
这Decision Strategy
是我们真正想要解决的问题。Decision
Strategy
可以是Unanimous
或。Affirmative
从文档中,
此配置更改策略评估引擎如何根据所有评估权限的结果决定是否应授予资源或范围。 意味着至少一个权限必须评估为一个积极的决定,以便授予对资源及其范围的访问权限。 意味着所有权限必须评估为积极的决定,以便最终决定也是积极的。例如,如果同一资源或范围的两个权限发生冲突(其中一个是授予访问权限,另一个是拒绝访问),如果选择的策略是肯定的,则将授予对该资源或范围的权限。否则,任何权限的单个拒绝也将拒绝对资源或范围的访问。
让我们用一个例子来更好地理解上面的内容。假设您有一个具有 2
个权限的资源,并且有人试图访问该资源(请记住,Logic
它Positive
适用于所有策略)。现在:
-
Permission One
有一Decision Strategy
组Affirmative
。它还有 3 个策略,每个策略都评估为:true
false
false
由于其中一项策略设置为true
,Permission One
因此设置为true
(肯定 - 只需 1 true
)。
-
Permission Two
有2Decision Strategy
个Unanimous
策略:true
false
在这种情况下Permission Two
,false
因为一项政策是错误的(一致 - 他们都需要true
)。
- 现在是 评估。如果资源服务器的
Decision Strategy
设置为Affirmative
,则将授予对该资源的访问权限,因为Permission One
istrue
。另一方面,如果资源服务器Decision Strategy
设置为Unanimous
,则访问将被拒绝。
看:
我们将继续重温这一点。Decision Strategy
我在第二部分解释了如何设置资源服务器。
因此,例如,我可以有权访问“帐户”和“查看”范围的权限,因此我将有权查看帐户吗?
简短的回答是肯定的。现在,让我们对此进行一些扩展:)
如果您有以下情况:
- 资源服务器
Decision Strategy
设置为Unanimous
或Affirmative
- 访问
account/{id}
资源的权限是true
- 访问
view
范围的权限是true
您将被授予查看帐户的权限。
-
true
+true
等于ortrue
下。Affirmative``Unanimous
Decision Strategy
现在如果你有这个
- 资源服务器
Decision Strategy
设置为Affirmative
- 访问
account/{id}
资源的权限是true
- 访问
view
范围的权限是false
您还将 被 授予查看该帐户的权限。
-
true
+false
在策略true
下。Affirmative
这里的重点是对给定资源的访问还取决于您的设置,因此请小心,因为您可能不希望出现第二种情况。
但我是否正确,这意味着我需要为用户可能属于的每个旧组制定策略?
我不确定 Keycloak 在 2 年前的表现如何,但您可以指定基于组的策略并简单地将所有组添加到该策略下。您当然不需要为每个组创建一个策略。
例如,如果我有一个“帮助台”角色,那么我需要一个“帮助台成员”策略,然后我可以将其添加到“viewAccount”权限。这个对吗?
差不多。您可以通过多种方式进行设置。例如,您可以:
- 创建您的资源(例如
/account/{id}
)并将其与account:view
范围相关联。 - 创建基于角色的策略并在该策略下添加
helpdesk
角色 - 创建一个
Scope-Based
名为的权限viewAccount
并将其与scope
,resource
和policy
我们将在第二部分设置类似的东西。
第二部分
Keycloak 有一个简洁的小工具,可让您测试所有策略。更好的是,您实际上不需要启动另一个应用程序服务器并部署一个单独的应用程序来工作。
这是我们将设置的场景:
- 我们将创建一个名为的新领域
stackoverflow-demo
- 我们将
bank-api
在该领域下创建一个客户端 - 我们将定义一个
/account/{id}
为该客户端调用的资源 -
account/{id}
遗嘱有account:view
范围 - 我们将
bob
在新领域下创建一个名为的用户 - 我们还将创建三个角色
bank_teller
:account_owner
和user
- 我们不会
bob
与任何角色相关联。现在不需要这个。
- 我们不会
- 我们将设置以下两个
Role-Based
策略:-
bank_teller
并account_owner
有权访问/account/{id}
资源 -
account_owner
可以访问account:view
范围 -
user
无权访问资源或范围
-
- 我们将使用该
Evaluate
工具来查看如何授予或拒绝访问权限。
请原谅我,这个例子不切实际,但我不熟悉银行业:)
钥匙披风设置
下载并运行 Keycloak
cd tmp
wget https://downloads.jboss.org/keycloak/8.0.0/keycloak-8.0.0.zip
unzip keycloak-8.0.0.zip
cd keycloak-8.0.0/bin
./standalone.sh
创建初始管理员用户
- 去
http://localhost:8080/auth
- 点击
Administration Console
链接 - 创建管理员用户并登录
访问入门了解更多信息。对于我们的目的,以上内容就足够了。
搭建舞台
创建一个新领域
- 将鼠标悬停在
master
领域周围,然后单击Add Realm
按钮。 - 输入
stackoverflow-demo
作为名称。 - 点击
Create
。 - 左上角现在应该说
stackoverflow-demo
而不是master
领域。
请参阅创建新领域
创建一个新用户
- 点击
Users
左侧的链接 - 点击
Add User
按钮 - 输入
username
(例如bob
) - 确保
User Enabled
已打开 - 点击
Save
请参阅创建新用户
创建新角色
- 点击
Roles
链接 - 点击
Add Role
- 添加以下角色
bank_teller
:account_owner
和user
同样,不要 您的用户与角色相关联。出于我们的目的,这不是必需的。
查看角色
创建客户端
- 点击
Clients
链接 - 点击
Create
- 输入
bank-api
_Client ID
- 对于
Root URL
输入http://127.0.0.1:8080/bank-api
- 点击
Save
- 确保这
Client Protocol
是openid-connect
- 更改
Access Type
为confidential
- 更改
Authorization Enabled
为On
- 向下滚动并点击
Save
。一个新的Authorization
标签应该出现在顶部。 - 单击
Authorization
选项卡,然后Settings
- 确保
Decision Strategy
设置为Unanimous
- 这是资源服务器的
Decision Strategy
- 这是资源服务器的
看:
创建自定义范围
- 单击
Authorization
选项卡 - 点击
Authorization Scopes
>Create
调出Add Scope
页面 - 输入
account:view
名称并按回车键。
创建“查看帐户资源”
- 点击上面的
Authorization
链接 - 点击
Resources
- 点击
Create
- 输入和
View Account Resource
_Name``Display name
- 输入
account/{id}
_URI
-
account:view
在Scopes
文本框中输入 - 点击
Save
请参阅创建资源
创建您的政策
- 再次在
Authorization
选项卡下,单击Policies
-
Role
从Create Policy
下拉列表中选择 - 在该
Name
部分中,键入Only Bank Teller and Account Owner Policy
- 在
Realm Roles
选择bank_teller
和account_owner
角色下 - 确保
Logic
设置为Positive
- 点击
Save
- 点击
Policies
链接 -
Role
从Create Policy
下拉列表中再次选择。 - 这次
Only Account Owner Policy
用于Name
- 在
Realm Roles
选择下account_owner
- 确保
Logic
设置为Positive
- 点击
Save
- 单击
Policies
顶部的链接,您现在应该会看到新创建的策略。
请参阅基于角色的策略
请注意,Keycloak 具有更强大的策略。请参阅管理策略
创建基于资源的权限
- 再次在
Authorization
选项卡下,单击Permissions
- 选择
Resource-Based
- 类型
View Account Resource Permission
为Name
- 根据
Resources
类型View Account Resource Permission
- 在
Apply Policy
选择下Only Bank Teller and Account Owner Policy
- 确保
Decision Strategy
设置为Unanimous
- 点击
Save
请参阅创建基于资源的权限
呸…
评估基于资源的权限
- 再次在
Authorization
选项卡下,选择Evaluate
- 在
User
输入下bob
- 在
Roles
选择下user
- 这是我们将我们的用户与我们创建的角色相关联的地方。
- 在
Resources
选择View Account Resource
并单击Add
- 点击评估。
- 展开
View Account Resource with scopes [account:view]
以查看结果,您应该会看到DENY
。
- 这是有道理的,因为我们只允许两个角色通过
Only Bank Teller and Account Owner Policy
. 让我们测试一下以确保这是真的! - 点击
Back
评估结果正上方的链接 - 将 bob 的角色更改为
account_owner
并单击Evaluate
。您现在应该看到结果为PERMIT
。如果您返回并将角色更改为,则相同的交易bank_teller
请参阅评估和测试策略
创建基于范围的权限
- 返回该
Permissions
部分 - 在下拉菜单下选择
Scope-Based
这个时间。Create Permission
- 在 下
Name
,输入View Account Scope Permission
- 在 下
Scopes
,输入account:view
- 在 下
Apply Policy
,输入Only Account Owner Policy
- 确保
Decision Strategy
设置为Unanimous
- 点击
Save
请参阅创建基于范围的权限
第二次试运行
评估我们的新变化
- 返回该
Authorization
部分 - 点击
Evaluate
- 用户应该是
bob
- 角色应该是
bank_teller
- 资源应该
View Account Resource
和点击Add
- 点击
Evaluate
,我们应该得到DENY
.- 同样,这应该不足为奇,因为
bank_teller
可以访问resource
但不能访问scope
. 这里一个权限评估为真,另一个为假。鉴于资源服务器的Decision Strategy
设置为Unanimous
,最终决定为DENY
。
- 同样,这应该不足为奇,因为
- 单击选项卡
Settings
下的,然后将其更改为并再次返回步骤 1-6。这一次,最终的结果应该是(一个权限是真的,所以最终的决定是真的)。Authorization``Decision Strategy``Affirmative``PERMIT
- 为了完整起见,将资源服务器
Decision Strategy
转回Unanimous
. 再次,返回到步骤 1 到 6,但这一次,将角色设置为account_owner
。这一次,最终结果又PERMIT
是有意义的,因为 可以account_owner
访问resource
和scope
。
整洁:) 希望这会有所帮助。
解决方法
我想使用 Keycloak 的授权系统创建一个相当简单的基于角色的访问控制系统。Keycloak
正在取代的系统允许我们创建一个“用户”,他是一个或多个“组”的成员。在这个遗留系统中,用户被授予“权限”来访问大约 250
个“能力”中的每一个,或者通过组成员身份(其中为组分配权限)或直接授予用户权限。
我想将遗留系统映射到 keycloak 授权。
将现有系统中的每个“功能”映射到一个 keycloak 资源和一组 keycloak
范围对我来说应该很简单。例如,“viewAccount”功能显然会映射到“帐户”资源和“视图”范围;并且“viewTransaction”映射到“事务”资源......但是最好的做法是只创建一个“视图”范围,并在多个资源(帐户、事务等)中使用它?或者我应该创建一个“viewAccount”范围、一个“viewTransaction”范围等?
同样,我对权限有点困惑。对于资源和范围的每个实际组合,通常的做法是创建权限吗?如果有多个权限匹配给定的资源/范围,Keycloak 会做什么?我猜
Keycloak 的目的是允许我配置针对资源和范围的权限矩阵,因此例如我可以有权访问“帐户”和“查看”范围的权限,因此我有权限查看帐户?
我问是因为这一切的结果似乎是我的旧“viewAccount”功能最终创建了一个“Account”资源,具有“View”范围和“viewAccount”权限,这似乎让我回到了原来的位置。这很好,如果它是正确的。
最后,显然我需要一组策略来确定是否应该应用
viewAccount。但我是否正确,这意味着我需要为用户可能属于的每个旧组制定策略?例如,如果我有一个“帮助台”角色,那么我需要一个“帮助台成员”策略,然后我可以将其添加到“viewAccount”权限。这个对吗?
谢谢,
标记
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。