我知道我迟到了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范围,以给定的帐户下的读取一个事务(毕竟,你可能需要访问帐户查看交易)。您的要求和标准将严重影响您的设计。
对于资源和范围的每种实用组合,是否通常创建许可?
抱歉,我不完全理解这个问题,所以我会比较宽泛。为了授予/拒绝访问resource,您需要:
- 定义您的政策
- 定义您的权限
- 将策略应用于权限
- 将您的权限与一个
scope或resource(或两者)关联
以便政策执行生效。请参阅授权过程。
如何设置所有这些完全取决于您。例如,您可以:
您有选择。
如果有多个权限匹配给定的资源/范围,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,Permission One因此设置为true(肯定-仅需要设置为1 true)。
Permission Two有一Decision Strategy组以Unanimous2种策略:
在这种情况下Permission Two是false因为一个策略是错误的(一致-它们都必须是true)。
- 现在进行最终评估。如果资源服务器的
Decision Strategy设置为Affirmative,访问该资源将被授予因为Permission One是true。另一方面,如果资源服务器的Decision Strategy设置为Unanimous,则访问将被拒绝。
看到:
我们将继续讨论。我将Decision Strategy 在第二部分中说明如何设置资源服务器。
因此,例如,我可以有权访问“帐户”和“查看”范围的权限,因此我将有权查看帐户?
简短的答案是肯定的。现在,让我们对此进行扩展:)
如果您具有以下情况:
- 资源服务器的
Decision Strategy设置为Unanimous或Affirmative
- 访问
account/{id}资源的权限为true
- 访问
view范围的权限为true
您将被授予查看该帐户的权限。
true+true等于或true之下。 AffirmativeUnanimous 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
- 我们将设置以下两个
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名称,然后按Enter。
创建“查看帐户资源”
- 点击上面的
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
请参阅创建基于资源的权限
ew ...
评估基于资源的权限
- 再次在
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。在这里,一个许可权评估为true,另一个许可权评估为false。鉴于资源服务器的Decision Strategy设置为Unanimous,最后的决定是DENY。
- 单击选项卡
Settings下的Authorization,然后将更Decision Strategy改为Affirmative,然后再次返回到步骤1-6。这次,最终结果应该是PERMIT(一个权限为真,所以最终决定为真)。
- 为了完整起见,请将资源服务器的位置
Decision Strategy重新设置为Unanimous。再次返回步骤1至6,但这一次将角色设置为account_owner。这次,最终的结果再次PERMIT变得有意义,因为可以account_owner访问resource和scope。
整洁:)希望这会有所帮助。