keycloak 中的资源、范围、权限和策略

如何解决keycloak 中的资源、范围、权限和策略

我知道我迟到了 2 年多,但我想我会分享我所知道的,并希望为未来的读者减轻一些痛苦。完全透明——我绝不是 Keycloak/OAuth/OIDC 专家,我所知道的主要来自阅读文档、书籍、优秀的 YouTube 和使用该工具。

这篇文章将由两部分组成:

  1. 我会尽我所能回答你所有的问题
  2. 我将向您展示如何在 Keycloak 中使用策略/范围/权限,而无需部署单独的应用程序,以便更好地理解此线程中的一些核心概念。请注意,这主要是为了让您开始。我正在使用Keycloak 8.0.0.

第一部分

开始之前的一些术语:

  • 在 Keycloak 中,您可以创建 2 种类型的权限:基于资源的和基于范围
  • 简而言之,对于Resource-Based权限,您将其直接应用于您的资源
  • 为了Scoped-Based获得许可,您将其应用于您的范围或范围 资源。

最好的做法是只创建一个“视图”范围,并在多个资源(帐户、事务等)中使用它?或者我应该创建一个“viewAccount”范围、一个“viewTransaction”范围等?

范围表示受保护资源的一组权限。在您的情况下,您有 2 个资源:accounttransaction,所以我倾向于第二种方法。

从长远来看,拥有view与所有资源(例如accounttransactioncustomersettlement)相关联的全局范围会使授权难以管理和适应安全需求更改。

以下是一些示例,您可以查看这些示例以了解设计

但请注意 - 我并不是说您不应该跨资源共享范围。事实上,Keycloak允许这对于具有相同的资源type。例如,您可能需要同时需要viewAccountviewTransaction范围来读取给定帐户下的交易(毕竟您可能需要访问该帐户才能查看交易)。您的要求和标准将严重影响您的设计。

对于资源和范围的每个实际组合,通常的做法是创建权限吗?

抱歉,我不完全理解这个问题,所以我会有点宽泛。为了授予/拒绝访问 a resource,您需要:

  • 定义您的政策
  • 定义您的权限
  • 将您的策略​​应用于您的权限
  • 将您的权限与一个scoperesource(或两者)相关联

使政策执行生效。请参阅授权流程

如何设置这一切完全取决于您。例如,您可以:

  • 定义单独的策略,并在适当的权限下绑定每个策略。

  • 更好的是,定义单个策略,然后将所有相关策略分组到一个aggregated策略(策略策略)下,然后将该聚合策略与scope-based权限相关联。您可以将该scoped-based权限同时应用于资源及其所有关联范围。

  • 或者,您可以通过利用这两种不同的类型来进一步分解您的权限。您可以通过权限类型单独为您的资源创建权限resource-based,并通过权限类型单独将其他权限与范围单独关联scope-based

你有选择。

如果有多个权限匹配给定的资源/范围,Keycloak 会做什么?

这取决于

  1. 资源服务器的 Decision Strategy
  2. 每个权限的Decision Strategy
  3. 每项政策的Logic价值。

Logic值与 Java 的!运算符类似。它可以是PositiveNegative。当LogicPositive时,策略的最终评估保持不变。当它Negative的 ,最终结果被否定(例如,如果一个策略评估为 false 并且它LogicNegative,那么它将是true)。为简单起见,我们假设Logic始终设置为Positive

Decision Strategy是我们真正想要解决的问题。Decision Strategy可以是Unanimous或。Affirmative从文档中,

此配置更改策略评估引擎如何根据所有评估权限的结果决定是否应授予资源或范围。 意味着至少一个权限必须评估为一个积极的决定,以便授予对资源及其范围的访问权限。 意味着所有权限必须评估为积极的决定,以便最终决定也是积极的。例如,如果同一资源或范围的两个权限发生冲突(其中一个是授予访问权限,另一个是拒绝访问),如果选择的策略是肯定的,则将授予对该资源或范围的权限。否则,任何权限的单个拒绝也将拒绝对资源或范围的访问。

让我们用一个例子来更好地理解上面的内容。假设您有一个具有 2 个权限的资源,并且有人试图访问该资源(请记住,LogicPositive适用于所有策略)。现在:

  1. Permission One有一Decision StrategyAffirmative。它还有 3 个策略,每个策略都评估为:
    • true
    • false
    • false

由于其中一项策略设置为truePermission One因此设置为true(肯定 - 只需 1 true)。

  1. Permission Two有2Decision StrategyUnanimous策略:
    • true
    • false

在这种情况下Permission Twofalse因为一项政策是错误的(一致 - 他们都需要true)。

  1. 现在是 评估。如果资源服务器的Decision Strategy设置为Affirmative,则将授予对该资源的访问权限,因为Permission Oneis true。另一方面,如果资源服务器Decision Strategy设置为Unanimous,则访问将被拒绝。

看:

我们将继续重温这一点。Decision Strategy 我在第二部分解释了如何设置资源服务器。

因此,例如,我可以有权访问“帐户”和“查看”范围的权限,因此我将有权查看帐户吗?

简短的回答是肯定的。现在,让我们对此进行一些扩展:)

如果您有以下情况:

  1. 资源服务器Decision Strategy设置为UnanimousAffirmative
  2. 访问account/{id}资源的权限是true
  3. 访问view范围的权限是true

您将被授予查看帐户的权限。

  • true+true等于ortrue下。 Affirmative``Unanimous Decision Strategy

现在如果你有这个

  1. 资源服务器Decision Strategy设置为Affirmative
  2. 访问account/{id}资源的权限是true
  3. 访问view范围的权限是false

您还将 授予查看该帐户的权限。

  • true+false在策略true下。Affirmative

这里的重点是对给定资源的访问还取决于您的设置,因此请小心,因为您可能不希望出现第二种情况。

但我是否正确,这意味着我需要为用户可能属于的每个旧组制定策略?

我不确定 Keycloak 在 2 年前的表现如何,但您可以指定基于组的策略并简单地将所有组添加到该策略下。您当然不需要为每个组创建一个策略。

例如,如果我有一个“帮助台”角色,那么我需要一个“帮助台成员”策略,然后我可以将其添加到“viewAccount”权限。这个对吗?

差不多。您可以通过多种方式进行设置。例如,您可以:

  1. 创建您的资源(例如/account/{id})并将其与account:view范围相关联。
  2. 创建基于角色的策略并在该策略下添加helpdesk角色
  3. 创建一个Scope-Based名为的权限viewAccount并将其与scope,resourcepolicy

我们将在第二部分设置类似的东西。

第二部分

Keycloak 有一个简洁的小工具,可让您测试所有策略。更好的是,您实际上不需要启动另一个应用程序服务器并部署一个单独的应用程序来工作。

这是我们将设置的场景:

  1. 我们将创建一个名为的新领域stackoverflow-demo
  2. 我们将bank-api在该领域下创建一个客户端
  3. 我们将定义一个/account/{id}为该客户端调用的资源
  4. account/{id}遗嘱有account:view范围
  5. 我们将bob在新领域下创建一个名为的用户
  6. 我们还将创建三个角色bank_telleraccount_owneruser
    • 我们不会bob与任何角色相关联。现在不需要这个。
  7. 我们将设置以下两个Role-Based策略:
    • bank_telleraccount_owner有权访问/account/{id}资源
    • account_owner可以访问account:view范围
    • user无权访问资源或范围
  8. 我们将使用该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

创建初始管理员用户

  1. http://localhost:8080/auth
  2. 点击Administration Console链接
  3. 创建管理员用户并登录

访问入门了解更多信息。对于我们的目的,以上内容就足够了。

搭建舞台

创建一个新领域

  1. 将鼠标悬停在master领域周围,然后单击Add Realm按钮。
  2. 输入stackoverflow-demo作为名称。
  3. 点击Create
  4. 左上角现在应该说stackoverflow-demo而不是master领域。

请参阅创建新领域

创建一个新用户

  1. 点击Users左侧的链接
  2. 点击Add User按钮
  3. 输入username(例如bob
  4. 确保User Enabled已打开
  5. 点击Save

请参阅创建新用户

创建新角色

  1. 点击Roles链接
  2. 点击Add Role
  3. 添加以下角色bank_telleraccount_owneruser

同样,不要 您的用户与角色相关联。出于我们的目的,这不是必需的。

查看角色

创建客户端

  1. 点击Clients链接
  2. 点击Create
  3. 输入bank-api_Client ID
  4. 对于Root URL输入http://127.0.0.1:8080/bank-api
  5. 点击Save
  6. 确保这Client Protocolopenid-connect
  7. 更改Access Typeconfidential
  8. 更改Authorization EnabledOn
  9. 向下滚动并点击Save。一个新的Authorization标签应该出现在顶部。
  10. 单击Authorization选项卡,然后Settings
  11. 确保Decision Strategy设置为Unanimous
    • 这是资源服务器的Decision Strategy

看:

创建自定义范围

  1. 单击Authorization选项卡
  2. 点击Authorization Scopes>Create调出Add Scope页面
  3. 输入account:view名称并按回车键。

创建“查看帐户资源”

  1. 点击上面的Authorization链接
  2. 点击Resources
  3. 点击Create
  4. 输入和View Account Resource_Name``Display name
  5. 输入account/{id}_URI
  6. account:viewScopes文本框中输入
  7. 点击Save

请参阅创建资源

创建您的政策

  1. 再次在Authorization选项卡下,单击Policies
  2. RoleCreate Policy下拉列表中选择
  3. 在该Name部分中,键入Only Bank Teller and Account Owner Policy
  4. Realm Roles选择bank_telleraccount_owner角色下
  5. 确保Logic设置为Positive
  6. 点击Save
  7. 点击Policies链接
  8. RoleCreate Policy下拉列表中再次选择。
  9. 这次Only Account Owner Policy用于Name
  10. Realm Roles选择下account_owner
  11. 确保Logic设置为Positive
  12. 点击Save
  13. 单击Policies顶部的链接,您现在应该会看到新创建的策略。

请参阅基于角色的策略

请注意,Keycloak 具有更强大的策略。请参阅管理策略

创建基于资源的权限

  1. 再次在Authorization选项卡下,单击Permissions
  2. 选择Resource-Based
  3. 类型View Account Resource PermissionName
  4. 根据Resources类型View Account Resource Permission
  5. Apply Policy选择下Only Bank Teller and Account Owner Policy
  6. 确保Decision Strategy设置为Unanimous
  7. 点击Save

请参阅创建基于资源的权限

呸…

评估基于资源的权限

  1. 再次在Authorization选项卡下,选择Evaluate
  2. User输入下bob
  3. Roles选择下user
    • 这是我们将我们的用户与我们创建的角色相关联的地方。
  4. Resources选择View Account Resource并单击Add
  5. 点击评估。
  6. 展开View Account Resource with scopes [account:view]以查看结果,您应该会看到DENY

在此处输入图像描述

  1. 这是有道理的,因为我们只允许两个角色通过Only Bank Teller and Account Owner Policy. 让我们测试一下以确保这是真的!
  2. 点击Back评估结果正上方的链接
  3. 将 bob 的角色更改为account_owner并单击Evaluate。您现在应该看到结果为PERMIT。如果您返回并将角色更改为,则相同的交易bank_teller

请参阅评估和测试策略

创建基于范围的权限

  1. 返回该Permissions部分
  2. 在下拉菜单下选择Scope-Based这个时间。Create Permission
  3. 在 下Name,输入View Account Scope Permission
  4. 在 下Scopes,输入account:view
  5. 在 下Apply Policy,输入Only Account Owner Policy
  6. 确保Decision Strategy设置为Unanimous
  7. 点击Save

请参阅创建基于范围的权限

第二次试运行

评估我们的新变化

  1. 返回该Authorization部分
  2. 点击Evaluate
  3. 用户应该是bob
  4. 角色应该是bank_teller
  5. 资源应该View Account Resource和点击Add
  6. 点击Evaluate,我们应该得到DENY.
    • 同样,这应该不足为奇,因为bank_teller可以访问resource但不能访问scope. 这里一个权限评估为真,另一个为假。鉴于资源服务器的Decision Strategy设置为Unanimous,最终决定为DENY
  7. 单击选项卡Settings下的,然后将其更改为并再次返回步骤 1-6。这一次,最终的结果应该是(一个权限是真的,所以最终的决定是真的)。Authorization``Decision Strategy``Affirmative``PERMIT
  8. 为了完整起见,将资源服务器Decision Strategy转回Unanimous. 再次,返回到步骤 1 到 6,但这一次,将角色设置为account_owner。这一次,最终结果又PERMIT是有意义的,因为 可以account_owner访问resourcescope

整洁:) 希望这会有所帮助。

解决方法

我想使用 Keycloak 的授权系统创建一个相当简单的基于角色的访问控制系统。Keycloak
正在取代的系统允许我们创建一个“用户”,他是一个或多个“组”的成员。在这个遗留系统中,用户被授予“权限”来访问大约 250
个“能力”中的每一个,或者通过组成员身份(其中为组分配权限)或直接授予用户权限。

我想将遗留系统映射到 keycloak 授权。

将现有系统中的每个“功能”映射到一个 keycloak 资源和一组 keycloak
范围对我来说应该很简单。例如,“viewAccount”功能显然会映射到“帐户”资源和“视图”范围;并且“viewTransaction”映射到“事务”资源......但是最好的做法是只创建一个“视图”范围,并在多个资源(帐户、事务等)中使用它?或者我应该创建一个“viewAccount”范围、一个“viewTransaction”范围等?

同样,我对权限有点困惑。对于资源和范围的每个实际组合,通常的做法是创建权限吗?如果有多个权限匹配给定的资源/范围,Keycloak 会做什么?我猜
Keycloak 的目的是允许我配置针对资源和范围的权限矩阵,因此例如我可以有权访问“帐户”和“查看”范围的权限,因此我有权限查看帐户?

我问是因为这一切的结果似乎是我的旧“viewAccount”功能最终创建了一个“Account”资源,具有“View”范围和“viewAccount”权限,这似乎让我回到了原来的位置。这很好,如果它是正确的。

最后,显然我需要一组策略来确定是否应该应用
viewAccount。但我是否正确,这意味着我需要为用户可能属于的每个旧组制定策略?例如,如果我有一个“帮助台”角色,那么我需要一个“帮助台成员”策略,然后我可以将其添加到“viewAccount”权限。这个对吗?

谢谢,

标记

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams['font.sans-serif'] = ['SimHei'] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -> systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping("/hires") public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate<String
使用vite构建项目报错 C:\Users\ychen\work>npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)> insert overwrite table dwd_trade_cart_add_inc > select data.id, > data.user_id, > data.course_id, > date_format(
错误1 hive (edu)> insert into huanhuan values(1,'haoge'); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive> show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 <configuration> <property> <name>yarn.nodemanager.res