授权服务指南
第 1 章 授权服务概述 复制链接链接已复制到粘贴板!
红帽构建的 Keycloak 支持细粒度授权策略,并可组合不同的访问控制机制,例如:
- 基于属性的访问控制(ABAC)
- 基于角色的访问控制(RBAC)
- 基于用户的访问控制(UBAC)
- 基于上下文的访问控制(CBAC)
基于规则的访问控制
- 使用 JavaScript
- 基于时间的访问控制
- 通过服务提供商接口(SPI)支持自定义访问控制机制(ACM)
红帽构建的 Keycloak 基于一组管理 UI 和 RESTful API,并提供为受保护的资源和范围创建权限的必要方法,将这些权限与授权策略相关联,并在应用程序和服务中强制实施授权决策。
资源服务器(应用程序或服务受保护的资源)通常依赖某种类型的信息来决定是否应向受保护的资源授予访问权限。对于基于 RESTful 的资源服务器,该信息通常从安全令牌获得,通常作为 bearer 令牌发送到服务器。对于依赖会话验证用户的 Web 应用,该信息通常存储在用户会话中,并从那里检索到每个请求。
通常,资源服务器仅根据基于角色的访问控制(RBAC)执行授权决策,其中授予了试图访问保护资源的用户的角色会根据映射到这些相同资源的角色进行检查。虽然角色对应用程序非常有用且使用,但有一些限制:
- 资源和角色与角色紧密耦合,更改角色(如添加、删除或更改访问上下文)可能会影响多个资源
- 对安全要求的更改可能会简化应用程序代码的更改以反映这些更改
- 根据您的应用程序大小,角色管理可能会变得困难,并容易出错
- 这不是最灵活的访问控制机制。角色不表示您是谁且缺少上下文信息。如果您被授予了一个角色,则至少有一些访问权限。
考虑到目前,我们需要考虑在不同区域间分发用户的异构环境,使用不同的本地策略、使用不同的设备以及高需求信息共享,红帽构建的 Keycloak 授权服务可帮助您通过提供以下服务来帮助您提高应用程序和服务的授权功能:
- 使用细粒度授权策略和不同的访问控制机制进行资源保护
- 集中式资源、权限和策略管理
- 集中策略决策点
- 基于一组基于 REST 的授权服务进行 REST 安全性
- 授权工作流和用户管理的访问
- 有助于避免跨项目(和重新部署)的代码复制,并快速适应您的安全要求。
1.1. 架构 复制链接链接已复制到粘贴板!
从设计的角度来看,授权服务基于一组精心定义的授权模式,提供以下功能:
策略管理点(PAP)
根据红帽构建的 Keycloak 管理控制台提供一组 UI,以管理资源服务器、资源、范围、权限和策略。这部分也可以通过使用 保护 API 远程完成。
策略决策点(PDP)
提供一个 distributable 策略决策,指向发送授权请求的位置,并使用请求的权限相应地评估策略。如需更多信息,请参阅 获取权限。
策略强制点(PEP)
为不同的环境提供实施,以便在资源服务器端实际实施授权决策。红帽构建的 Keycloak 提供了一些内置 策略 Enforcers。
策略信息点(PIP)
基于红帽构建的 Keycloak 身份验证服务器,您可以在评估授权策略的过程中从身份和运行时环境获取属性。
1.1.1. 授权过程 复制链接链接已复制到粘贴板!
三个主要流程定义了了解如何使用红帽构建的 Keycloak 启用精细授权应用程序所需的步骤:
- 资源管理
- 权限和策略管理
- 策略强制
1.1.1.1. 资源管理 复制链接链接已复制到粘贴板!
资源管理 涉及定义正在保护的内容的所有必要步骤。
首先,您需要指定您要保护的 Keycloak 的红帽构建,这通常代表 web 应用程序或一组一个或多个服务。有关资源服务器的更多信息,请参阅 术语。
资源服务器使用红帽构建的 Keycloak 管理控制台进行管理。您可以启用任何注册的客户端应用程序作为资源服务器,并开始管理您要保护的资源和范围。
资源可以是网页、RESTFul 资源、文件系统中的文件、EJB 等。它们可以表示一组资源(就像 Java 中的类),也可以代表单个和特定资源。
例如,您可能有一个代表所有 银行 帐户的银行帐户资源,并使用它来定义所有银行帐户通用的授权策略。但是,您可能希望为 alice 帐户 (属于客户的资源实例)定义特定策略,其中只有所有者才能访问某些信息或执行操作。
资源可以使用红帽构建的 Keycloak 管理控制台或 保护 API 进行管理。在后者的情况下,资源服务器能够远程管理其资源。
范围通常代表可以对资源执行的操作,但不仅限于它们。您还可以使用范围代表资源中的一个或多个属性。
1.1.1.2. 权限和策略管理 复制链接链接已复制到粘贴板!
在定义了资源服务器以及要保护的所有资源后,您必须设置权限和策略。
这个过程涉及实际定义管理资源的安全性和访问要求所需的所有步骤。
策略定义必须满足访问或对某个资源(资源或范围)执行操作的条件,但它们不会与受保护的内容相关联。它们是通用的,可以被重新用于构建权限甚至更复杂的策略。
例如,要仅允许具有"用户高级"角色的用户访问一组资源,您可以使用 RBAC (基于角色的访问控制)。
红帽构建的 Keycloak 提供了几个内置策略类型(及其相应的策略供应商)涵盖了最常见的访问控制机制。您甚至可以根据使用 JavaScript 编写的规则创建策略。
定义了策略后,您可以开始定义您的权限。权限与它们保护的资源相结合。在这里,您可以指定您要保护的内容(资源或范围)以及必须满足授予或拒绝权限的策略。
1.1.1.3. 策略强制 复制链接链接已复制到粘贴板!
策略强制 涉及为资源服务器实际实施授权决策所需的步骤。这可以通过在能够与授权服务器通信的资源服务器上启用 策略强制点 或 PEP 来实现,请求授权数据并根据服务器返回的决策和权限控制对受保护的资源的访问。
Red Hat build of Keycloak 提供一些内置策略强制实现,您可以根据应用程序运行的平台来保护应用程序。???
1.1.2. 授权服务 复制链接链接已复制到粘贴板!
授权服务由以下 RESTFul 端点组成:
- 令牌端点
- 资源管理端点
- 权限管理端点
这些服务各自提供一个特定的 API,涵盖了授权过程中涉及的不同步骤。
1.1.2.1. 令牌端点 复制链接链接已复制到粘贴板!
OAuth2 客户端(如前端应用)可以使用令牌端点从服务器获取访问令牌,并使用这些令牌来访问由资源服务器(如后端服务)保护的资源。同样,红帽构建的 Keycloak 授权服务为 OAuth2 提供扩展,以便根据处理与所请求的资源或范围关联的所有策略来发布访问令牌。这意味着资源服务器可以根据服务器授予的权限并由访问令牌来强制访问其受保护的资源。在 Red Hat build of Keycloak Authorization Services 中,带有权限的访问令牌被称为 Requesting Party Token 或 RPT。
1.1.2.2. 保护 API 复制链接链接已复制到粘贴板!
Protection API 是一组与 UMA 兼容的 端点,为资源服务器提供操作,以帮助它们管理其关联的资源、范围、权限和策略。只有资源服务器可以访问此 API,这还需要 uma_protection 范围。
保护 API 提供的操作可在两个主要组中组织:
资源管理
- 创建资源
- 删除资源
- 通过 Id 查找
- 查询
权限管理
- 问题权限标题
默认情况下启用远程资源管理。您可以使用红帽构建的 Keycloak 管理控制台更改,只允许通过控制台进行资源管理。
使用 UMA 协议时,保护 API 的权限 Tickets 是整个授权过程的重要部分。如后续小节中所述,它们代表客户端请求的权限,并发送到服务器,以获取在评估与所请求资源和范围相关联的权限和范围时授予的所有权限的最终令牌。
1.2. 术语 复制链接链接已复制到粘贴板!
在进一步操作前,了解红帽构建的 Keycloak 授权服务引入的这些术语和概念非常重要。
1.2.1. 资源服务器 复制链接链接已复制到粘贴板!
对于每个 OAuth2 术语,资源服务器是托管受保护的资源并能够接受和响应受保护的资源请求的服务器。
资源服务器通常依赖于某种类型的信息来确定是否应授予对受保护资源的访问。对于基于 RESTful 的资源服务器,该信息通常以安全令牌的形式传输,通常作为 bearer 令牌以及对服务器的每次请求发送。依赖会话来验证用户的 Web 应用通常会将该信息存储在用户会话中,并从那里检索信息,以供每个请求使用。
在 Red Hat build of Keycloak 中,任何 机密 客户端应用程序都可以充当资源服务器。此客户端的资源及其对应范围受一组授权策略保护和管理。
1.2.2. 资源 复制链接链接已复制到粘贴板!
资源是应用程序和组织资产的一部分。它可以是一个或多个端点、一个典型的 Web 资源,如 HTML 页面等。在授权策略术语中,资源是受保护的 对象。
每个资源都有唯一标识符,可以代表单个资源或一组资源。例如,您可以管理一个 银行帐户资源,其代表并为所有银行帐户定义一组授权策略。但是,您也可以将不同的资源命名为 alice's banking Account,它代表单个客户拥有的单个资源,他们可以拥有自己的授权策略集。
1.2.3. 影响范围 复制链接链接已复制到粘贴板!
资源范围是可能对资源执行的有界范围的访问权限。在授权策略术语中,范围是可能会以逻辑方式应用到资源的一些 操作动词 之一。
它通常表示可以使用给定资源完成什么操作。范围示例包括 view、edit、delete 等。但是,范围也可以与资源提供的特定信息相关。在这种情况下,您可以具有项目资源和成本范围,其中成本范围用于定义特定策略和权限,供用户访问项目的成本。
1.2.4. 权限 复制链接链接已复制到粘贴板!
考虑这个简单和非常常见的权限:
权限将受保护的对象与必须评估的策略相关联,以确定是否授予访问权限。
X 可在资源 Z 上执行 Y
where …
- X 代表一个或多个用户、角色或组,或者它们的组合。您也可以在此处使用声明和上下文。
- y 代表要执行的操作,如 write、view 等。
- z 代表受保护的资源,如 "/accounts"。
Red Hat build of Keycloak 提供了一个丰富的平台,用于构建范围从简单到非常复杂的、基于规则的动态权限。它提供灵活性并有助于:
- 降低代码重构和权限管理成本
- 支持更灵活的安全模型,帮助您轻松适应安全要求的变化
- 在运行时进行更改;应用程序只关注受保护的资源和范围,而不关注它们是如何保护的。
1.2.5. 策略 复制链接链接已复制到粘贴板!
策略定义了必须满足授予对象访问权限的条件。与权限不同,您没有指定受保护的对象,而是对给定对象(如资源、范围或两者)满足的条件。策略与可用于保护资源的不同访问控制机制(ACM)密切相关。使用策略,您可以为属性的访问控制(ABAC)、基于角色的访问控制(RBAC)、基于上下文的访问控制或其中的任何组合实施策略。
红帽 Keycloak 的构建利用策略的概念以及如何通过提供聚合策略的概念来定义它们,您可以在其中构建"策略策略",并仍然控制评估的行为。对于可以访问给定资源的所有条件,而不是编写一个大型策略,红帽构建的 Keycloak 授权服务中的策略实施遵循划分和拥塞技术。也就是说,您可以创建单独的策略,然后将它们与不同的权限重复使用,并通过组合单个策略来构建更复杂的策略。
1.2.6. 策略供应商 复制链接链接已复制到粘贴板!
策略提供程序是特定策略类型的实现。Red Hat build of Keycloak 提供内置的策略,由对应的策略供应商支持,您可以创建自己的策略类型来支持您的特定要求。
Red Hat build of Keycloak 提供了一个 SPI (Service Provider Interface),可用于插入您自己的策略供应商实现。
1.2.7. 权限票据 复制链接链接已复制到粘贴板!
权限票据是由用户管理访问(UMA)规范定义的特殊令牌类型,它提供由授权服务器决定的不透明结构。此结构代表了客户端所请求的资源和/或范围、访问上下文以及必须应用到授权数据请求的策略(请求方令牌 [RPT])。
在 UMA 中,权限票据对于支持个人对人共享以及个人对组织共享至关重要。使用授权工作流的权限票据可启用一系列很复杂的场景,其中资源所有者和资源服务器可根据管理这些资源访问权限的细粒度策略完全控制其资源。
在 UMA 工作流中,授权服务器向资源服务器发出权限票据,这会将权限票据返回到尝试访问受保护的资源的客户端。客户端收到票据后,它可以通过向授权服务器发送票据来请求 RPT (一个最终令牌保存授权数据)。
第 2 章 开始使用 复制链接链接已复制到粘贴板!
对于某些应用程序,您可以查看以下资源来快速开始使用红帽构建的 Keycloak 授权服务:
- 在 Wildfly 中保护 JakartaEE 应用程序
- 保护 Spring Boot 应用程序
- 保护 Quarkus 应用程序
- 保护 应用程序部分中的 Keycloak Node.js 适配器
第 3 章 管理资源服务器 复制链接链接已复制到粘贴板!
根据 OAuth2 规范,资源服务器是托管受保护的资源并能够接受和响应受保护的资源请求的服务器。
在 Red Hat build of Keycloak 中,资源服务器提供了一个丰富的平台,为保护的资源启用精细的授权授权,其中可以根据不同的访问控制机制做出授权决策。
任何客户端应用程序都可以配置为支持细粒度权限。这样一来,您在概念上将客户端应用程序转变为资源服务器。
3.1. 创建客户端应用程序 复制链接链接已复制到粘贴板!
启用红帽构建的 Keycloak 授权服务的第一步是创建您要转换为资源服务器的客户端应用程序。
流程
点 Clients。
客户端
在此页面上,单击 Create。
添加客户端
-
键入客户端的客户端 ID。例如,my-resource-server。 输入应用程序的
Root URL。例如:http://${host}:${port}/my-resource-serverhttp://${host}:${port}/my-resource-serverCopy to Clipboard Copied! Toggle word wrap Toggle overflow 点 Save。客户端已创建,并且客户端 Settings 页面将打开。此时会显示类似如下的页面:
客户端设置
3.2. 启用授权服务 复制链接链接已复制到粘贴板!
您可以将 OIDC 客户端转换为资源服务器并启用细粒度授权。
流程
- 在客户端设置页面中,向下滚动到 Capability Config 部分。
- 将 "启用 "切换为 On。
点击 Save。
启用授权服务
此客户端会显示一个新的 Authorization 选项卡。点击 Authorization 选项卡,并显示类似如下的页面:
资源服务器设置
Authorization 选项卡包含额外的子选项卡,涵盖了您必须遵循的不同步骤来实际保护应用程序的资源。每个标签页分别在本文档的特定主题中单独介绍。但这里是有关每个问题的快速描述:
3.2.1. 资源服务器设置 复制链接链接已复制到粘贴板!
在 Resource Server Settings 页面中,您可以配置策略强制模式,允许远程资源管理,并导出授权配置设置。
策略强制模式
指定在处理发送到服务器的授权请求时如何强制实施策略。
Enforcing
(默认模式)默认拒绝请求,即使没有与给定资源关联的策略。
Permissive
即使没有与给定资源关联的策略,也允许请求。
Disabled
禁用所有策略的评估,并允许访问所有资源。
决策策略
此配置会改变策略评估引擎如何根据所有评估的权限中结果授予资源或范围的方式。
Affirmative表示,至少有一个权限必须评估到正决策,才能授予对资源及其范围的访问权限。不明确意味着所有权限都必须评估到积极的决定,才能最终决定也是正面的决定。例如,如果同一资源或范围的两个权限存在冲突(其中一个是授予访问权限,另一个是拒绝访问),则如果所选策略是效率的,则会授予资源或范围的权限。否则,来自任何权限的单个拒绝也会拒绝对资源或范围的访问。远程资源管理
指定资源是否可以由资源服务器远程管理。如果为 false,则只能从管理控制台管理资源。
3.3. 默认配置 复制链接链接已复制到粘贴板!
当您创建资源服务器时,红帽构建的 Keycloak 会为新创建的资源服务器创建一个默认配置。
默认配置包括:
- 代表应用程序中的所有资源的默认保护资源。
- 始终授予对此策略保护的资源的访问权限的策略。
- 根据默认策略监管对所有资源的访问的权限。
默认受保护的资源称为 默认资源,如果您进入到 Resources 选项卡,可以查看它。
默认资源
此资源定义了 Type,即 urn:my-resource-server:resources:default 和一个 URI configured。在这里,URI 字段定义了一个通配符模式,指示红帽构建 Keycloak,此资源代表应用程序中的所有路径。换句话说,在 为您的应用程序启用策略强制 时,会在授予访问权限前检查与资源关联的所有权限。
前面提到的 Type 定义了一个值,可用于创建 类型的资源,该权限必须应用到默认资源或您使用相同的类型创建的任何其他资源。
默认策略称为 唯一的域策略,如果您进入到 Policies 选项卡,可以查看该策略。
默认策略
此策略是基于 JavaScript 的策略,定义一个条件,始终授予对此策略保护的资源的访问权限。如果您点此策略,您可以看到它定义了如下规则:
// by default, grants any permission associated with this policy $evaluation.grant();
// by default, grants any permission associated with this policy
$evaluation.grant();
最后,默认权限称为默认权限,您可以通过 Permissions 标签页来查看它。
默认权限
此权限是基于 资源的权限,定义一个或多个策略的集合,它们应用到给定类型的所有资源。
3.3.1. 更改默认配置 复制链接链接已复制到粘贴板!
您可以通过删除默认资源、策略或权限定义并创建您自己的默认配置。
默认资源使用映射到应用程序中的任何资源或路径的 URI 创建,使用 /* 模式。在创建自己的资源、权限和策略前,请确保默认配置不会与您自己的设置冲突。
默认配置定义了一个资源,它映射到应用程序中的所有路径。如果您要将权限写入您自己的资源,请务必删除默认 资源,或者将其 字段更改为应用程序中更具体的路径。否则,与默认资源关联的策略(默认始终授予访问权限)将允许红帽构建 Keycloak 授予对任何受保护的资源的访问权限。
URIS
3.4. 导出和导入授权配置 复制链接链接已复制到粘贴板!
可以导出并下载资源服务器(或客户端)的配置设置。您还可以为资源服务器导入现有的配置文件。当您要为资源服务器创建初始配置或更新现有配置时,导入和导出配置文件会很有用。配置文件包含以下的定义:
- 保护的资源和范围
- 策略(policy)
- 权限
3.4.1. 导出配置文件 复制链接链接已复制到粘贴板!
流程
- 点菜单中的 Clients。
- 单击您创建的客户端作为资源服务器。
点 Export 选项卡。
导出设置
配置文件以 JSON 格式导出,并以文本区域显示,您可以从中复制和粘贴。您还可以点 Download 下载配置文件并保存它。
3.4.2. 导入配置文件 复制链接链接已复制到粘贴板!
您可以为资源服务器导入配置文件。
流程
导航到 Resource Server Settings 页面。
导入设置
- 点 Import 并选择包含您要导入的配置的文件。
第 4 章 管理资源和范围 复制链接链接已复制到粘贴板!
资源管理简单且通用。创建资源服务器后,您可以开始创建您要保护的资源和范围。资源和范围可以通过分别导航到 Resource 和 Authorization Scopes 选项卡来管理。
4.1. 查看资源 复制链接链接已复制到粘贴板!
在 Resource 页面中,您会看到与资源服务器关联的资源列表。
Resources
资源列表提供有关受保护的资源的信息,例如:
- 类型
- URI
- 所有者
- 关联的范围(若有)
- 关联的权限
在此列表中,您可以通过单击您要为其创建权限的资源的 Create Permission 来直接创建一个权限。
在为资源创建权限前,请确定您已定义了您要与权限关联的策略。
4.2. 创建资源 复制链接链接已复制到粘贴板!
创建资源非常简单且通用。您的主要关注点是您创建的资源的粒度。换句话说,可创建资源来表示一个或多个资源的集合,您定义资源对于管理权限至关重要。
若要创建新资源,可单击 Create resource。
添加资源
在 Red Hat build of Keycloak 中,资源定义了一组通用的、不同类型资源的信息,例如:
Name
描述此资源的人类可读和唯一字符串。
类型
唯一标识一个或多个资源集合的类型的字符串。type 是用于对不同资源实例进行分组的字符串。例如,自动创建的默认资源的默认类型是
urn:resource-server-name:resources:default
URIS
为资源提供位置/地址的 URIS。对于 HTTP 资源,URIS 通常是用于提供这些资源的相对路径。
范围
与资源关联的一个或多个范围。
4.2.1. 资源属性 复制链接链接已复制到粘贴板!
资源可能关联有属性。这些属性可用于提供有关资源的额外信息,并在评估与资源关联的权限时向策略提供额外的信息。
每个属性是一个键和值对,值可以是一个或多个字符串的集合。通过使用逗号分隔每个值,可以为一个属性定义多个值。
4.2.2. 类型的资源 复制链接链接已复制到粘贴板!
资源的 type 字段可用于将不同的资源分组在一起,以便可以使用一组通用的权限来加以保护。
4.2.3. 资源所有者 复制链接链接已复制到粘贴板!
资源也具有所有者。默认情况下,资源由资源服务器拥有。
但是,资源也可以与用户关联,因此您可以根据资源所有者创建权限。例如,只有资源所有者才可以删除或更新给定的资源。
4.2.4. 远程管理资源 复制链接链接已复制到粘贴板!
资源管理也通过 保护 API 公开,以允许资源服务器远程管理其资源。
使用保护 API 时,可以实施资源服务器来管理其用户拥有的资源。在这种情况下,您可以指定用户标识符,将资源配置为属于特定用户。
红帽构建的 Keycloak 提供资源服务器完全控制其资源。以后,我们应当能够允许用户控制自己的资源,并批准授权请求并管理权限,特别是在使用 UMA 协议时。
第 5 章 管理策略 复制链接链接已复制到粘贴板!
如前文所述,策略定义了在授予对象访问权限前必须满足的条件。
流程
点 Policy 选项卡查看与资源服务器关联的所有策略。
策略(policy)
在这个标签页中,您可以查看之前创建的策略列表,以及创建和编辑策略。
若要创建新策略,可单击 Create policy,然后从列表中选择策略类型。
有关每种策略类型的详情,请参考本节。
5.1. 基于用户的策略 复制链接链接已复制到粘贴板!
您可以使用此类策略为允许一个或多个用户访问对象的权限定义条件。
要创建基于用户的新策略,请在策略列表右上角的项目列表中选择 User。
添加用户策略
5.1.1. Configuration 复制链接链接已复制到粘贴板!
Name
标识策略的人类可读和唯一字符串。最佳实践是使用与您的业务和安全要求紧密相关的名称,以便您可以更轻松地识别它们。
描述
包含此策略详情的字符串。
用户
指定哪些用户被授予此策略的访问权限。
逻辑
评估完其他条件后要应用的此策略逻辑。
5.2. 基于角色的策略 复制链接链接已复制到粘贴板!
您可以使用此类策略为允许一个或多个角色访问对象的权限定义条件。
默认情况下,不会根据需要指定添加到此策略的角色,如果请求访问权限的用户被授予了任何这些角色,策略将授予访问权限。但是,如果要强制执行特定的角色,您可以根据需要指定一个特定的角色为 required。您还可以组合使用 required 和 non-required 角色,无论它们是 realm 或 client 角色。
当您需要更严格的基于角色的访问控制(RBAC)时,角色策略很有用,其中必须强制执行特定的角色才能授予对象的访问权限。例如,您可以强制用户必须同意允许客户端应用程序(代表用户代表)访问用户的资源。您可以使用红帽构建的 Keycloak 客户端范围映射来启用同意页面,甚至强制客户端在从红帽构建的 Keycloak 服务器获取访问令牌时明确提供范围。
要创建基于角色的新策略,请从策略类型列表中选择 Role。
添加角色策略
5.2.1. Configuration 复制链接链接已复制到粘贴板!
Name
描述该策略的人类可读和唯一字符串。最佳实践是使用与您的业务和安全要求紧密相关的名称,以便您可以更轻松地识别它们。
描述
包含此策略详情的字符串。
realm 角色
指定哪些 realm 角色被这个策略允许。
客户端角色
指定哪些 client 角色被这个策略允许。若要启用此字段,必须首先选择一个
客户端。获取角色
默认情况下,仅使用授权请求发送的令牌中提供的角色来检查该用户是否被授予角色。如果启用了此设置,策略将忽略来自令牌的角色,并检查与用户关联的任何角色。
逻辑
评估完其他条件后要应用的此策略逻辑。
5.2.2. 根据需要定义角色 复制链接链接已复制到粘贴板!
在创建基于角色的策略时,您可以根据需要指定特定的角色 。当这样做时,只有在用户请求访问被授予了所有 required 角色时才会授予访问权限。realm 和 client 角色都可配置,如下所示。
所需角色示例
要根据需要指定角色,请根据需要为您要配置的角色选择 Required 复选框。
当策略定义多个角色时,必需的角色很有用,但只有它们的子集是必需的。在这种情况下,您可以组合 realm 和客户端角色,为应用程序启用更精细的基于角色的访问控制(RBAC)模型。例如,您可以拥有特定于客户端的策略,并且需要与该客户端关联的特定客户端角色。或者,您可以强制仅在存在特定 realm 角色时才会授予访问权限。您还可以组合使用同一策略中的这两种方法。
5.3. 基于 JavaScript 的策略 复制链接链接已复制到粘贴板!
如果您的策略实施使用基于属性的访问控制(ABAC),则请确保用户无法编辑受保护的属性,并且相应的属性为只读。请参阅 Threat 模型缓解 章节中的详细信息。
您可以使用这类策略,通过 JavaScript 为权限定义条件。它是红帽构建的 Keycloak 支持的基于规则的策略类型之一,它提供了根据 评估 API 编写任何策略的灵活性。
要创建新的基于 JavaScript 的策略,请在策略列表右上角的 item 列表中选择 JavaScript。
默认情况下,无法将 JavaScript 策略上传到服务器。您应该更喜欢直接将 JS 策略部署到服务器,如 JavaScript 提供程序 中所述。
5.3.1. 从部署的 JAR 文件创建 JS 策略 复制链接链接已复制到粘贴板!
Red Hat build of Keycloak 允许您部署 JAR 文件,以便将脚本部署到服务器。如需了解更多详细信息,请参阅 JavaScript Providers。
部署脚本后,您应能够从可用的策略提供程序列表中选择部署的脚本。
5.3.2. 例子 复制链接链接已复制到粘贴板!
5.3.2.1. 从评估上下文中检查属性 复制链接链接已复制到粘贴板!
以下是基于 JavaScript 的策略的简单示例,它使用基于属性的访问控制(ABAC)根据从执行上下文获取的属性来定义条件:
5.3.2.2. 从当前身份检查属性 复制链接链接已复制到粘贴板!
以下是基于 JavaScript 的策略的简单示例,它使用基于属性的访问控制(ABAC)根据与当前身份关联的属性来定义条件:
这些属性从授权请求中使用的令牌中定义的任何声明映射。
5.3.2.3. 检查授予当前身份的角色 复制链接链接已复制到粘贴板!
您还可以在策略中使用基于角色的访问控制(RBAC)。在以下示例中,我们检查是否被授予了 keycloak_user 域角色的用户 :
或者,您可以检查用户是否被授予 my-client-role 客户端角色,其中 my-client 是客户端应用程序的客户端 ID:
5.3.2.4. 检查授予用户的角色 复制链接链接已复制到粘贴板!
检查授予用户的域角色:
const realm = $evaluation.getRealm();
if (realm.isUserInRealmRole('marta', 'role-a')) {
$evaluation.grant();
}
const realm = $evaluation.getRealm();
if (realm.isUserInRealmRole('marta', 'role-a')) {
$evaluation.grant();
}
或用于授予用户的客户端角色:
const realm = $evaluation.getRealm();
if (realm.isUserInClientRole('marta', 'my-client', 'some-client-role')) {
$evaluation.grant();
}
const realm = $evaluation.getRealm();
if (realm.isUserInClientRole('marta', 'my-client', 'some-client-role')) {
$evaluation.grant();
}
5.3.2.5. 检查授予组的角色 复制链接链接已复制到粘贴板!
检查为组授予的域角色:
const realm = $evaluation.getRealm();
if (realm.isGroupInRole('/Group A/Group D', 'role-a')) {
$evaluation.grant();
}
const realm = $evaluation.getRealm();
if (realm.isGroupInRole('/Group A/Group D', 'role-a')) {
$evaluation.grant();
}
5.3.2.6. 将任意声明推送到资源服务器 复制链接链接已复制到粘贴板!
要将任意声明推送到资源服务器,以便提供有关如何强制实施权限的附加信息:
5.3.2.7. 检查组成员资格 复制链接链接已复制到粘贴板!
const realm = $evaluation.getRealm();
if (realm.isUserInGroup('marta', '/Group A/Group B')) {
$evaluation.grant();
}
const realm = $evaluation.getRealm();
if (realm.isUserInGroup('marta', '/Group A/Group B')) {
$evaluation.grant();
}
5.3.2.8. 混合不同的访问控制机制 复制链接链接已复制到粘贴板!
您还可以使用多种访问控制机制的组合。以下示例显示了如何在相同的策略中使用 roles (RBAC)和 claim/attributes (ABAC)检查。在这种情况下,我们检查用户是否被授予 admin 角色,或者具有来自 keycloak.org 域的电子邮件:
在编写自己的规则时,请注意 $evaluation 对象是实施 org.keycloak.authorization.policy.evaluation.Evaluation.Evaluation 的对象。有关您可以从此接口访问的内容的更多信息,请参阅 评估 API。
5.4. 基于时间的策略 复制链接链接已复制到粘贴板!
您可以使用这种类型的策略为您的权限定义时间条件。
要创建新的基于时间的策略,请在策略列表右上角的项目列表中选择 Time。
添加时间策略
5.4.1. Configuration 复制链接链接已复制到粘贴板!
Name
描述该策略的人类可读和唯一字符串。最佳实践是使用与您的业务和安全要求紧密相关的名称,以便您可以更轻松地识别它们。
描述
包含此策略详情的字符串。
开始时间
定义 不得 授予访问权限前的时间。只有在当前日期/时间早于这个值时,才会授予权限。
过期时间
定义 不得 授予访问权限的时间。只有在当前日期/时间早于这个值时,才会授予权限。选择 Repeat 以重复对特定日期的 Month、 Month 、Year、Hour 或 Minute 的访问权限。
Month of Month
定义必须授予访问权限的月的日期。您还可以指定日期范围。在这种情况下,只有在月份的当前日期介于或等于指定的值时,才会授予权限。
月
定义必须授予访问权限的月。您还可以指定多个月。在这种情况下,只有在当前月份介于或等于指定的两个值时才授予权限。
年
定义必须授予访问权限的年份。您还可以指定年范围。在这种情况下,只有在当前年间或等于指定的两个值时才会授予权限。
hour
定义必须授予访问权限的小时。您还可以指定小时范围。在这种情况下,只有在当前小时介于或等于指定的两个值时,才会授予权限。
minute
定义必须授予访问权限的分钟。您还可以指定分钟范围。在这种情况下,只有在当前分钟介于或等于指定的两个值时才授予权限。
逻辑
评估完其他条件后要应用的此策略逻辑。
只有在满足所有条件时,才会授予访问权限。红帽构建的 Keycloak 将根据每个条件的结果执行 AND。
5.5. 聚合策略 复制链接链接已复制到粘贴板!
如前文所述,红帽构建的 Keycloak 允许您构建策略策略,一个概念称为策略聚合。您可以使用策略聚合来重复使用现有策略来构建更复杂的策略,并使您的权限更加分离,与处理授权请求期间评估的策略更加分离。
要创建新的聚合策略,请在策略列表右上角的项目列表中选择 Aggregated。
添加一个聚合策略
假设有一个名为 Confidential Resource 的资源,该资源只能由来自 keycloak.org 域的用户以及特定的 IP 地址访问。您可以创建一个具有这两个条件的单一策略。但是,无论原始网络是什么,您想要重复使用此策略的域部分来应用到操作的权限。
您可以为域和网络条件创建单独的策略,并根据这两个策略的组合创建第三个策略。通过聚合策略,您可以自由组合其他策略,然后将新的聚合策略应用到您需要的任何权限。
在创建聚合策略时,请注意,您不会引入策略之间的循环参考或依赖项。如果检测到循环依赖项,则无法创建或更新策略。
5.5.1. Configuration 复制链接链接已复制到粘贴板!
Name
描述该策略的人类可读和唯一字符串。我们强烈建议您使用与您的业务和安全要求紧密相关的名称,以便您可以更轻松地识别它们,并了解它们的含义。
描述
包含有关此策略的更多详细信息的字符串。
应用策略
定义与聚合策略关联的一个或多个策略的集合。要关联策略,您可以选择现有策略,或者通过选择您要创建的策略类型来创建新策略。
决策策略
此权限的决策策略。
逻辑
评估完其他条件后要应用的此策略逻辑。
5.5.2. 聚合策略的决策策略 复制链接链接已复制到粘贴板!
在创建聚合策略时,您还可以定义将根据每个策略的结果来确定最终决策的决策策略。
unanimous
如果不提供任何策略,则默认策略。在这种情况下,所有策略都 必须评估对最终决策的积极决定。
Affirmative
在这种情况下,至少有一个 策略必须评估到正决策,以便最终决定也是正面的决定。
consensus
在这种情况下,正决策的数量必须大于负决策的数量。如果正和负决策的数量相同,最终决策将是负数。
5.6. 基于客户端的策略 复制链接链接已复制到粘贴板!
您可以使用此类策略为允许一个或多个客户端访问对象的权限定义条件。
要创建基于客户端的新策略,请从策略类型列表中选择 Client。
添加客户端策略
5.6.1. Configuration 复制链接链接已复制到粘贴板!
Name
标识策略的人类可读和唯一字符串。最佳实践是使用与您的业务和安全要求紧密相关的名称,以便您可以更轻松地识别它们。
描述
包含此策略详情的字符串。
客户端
指定此策略具有基于Group 的策略访问哪些客户端。
逻辑
评估完其他条件后要应用的此策略逻辑。
5.7. 基于组的策略 复制链接链接已复制到粘贴板!
您可以使用此类策略为权限定义条件,其中允许一个或多个组(及其层次结构)访问对象。
要创建基于组的新策略,请从策略类型列表中选择 Group。
组策略
5.7.1. Configuration 复制链接链接已复制到粘贴板!
Name
描述该策略的人类可读和唯一字符串。最佳实践是使用与您的业务和安全要求紧密相关的名称,以便您可以更轻松地识别它们。
描述
包含此策略详情的字符串。
组声明
指定令牌中的声明名称,其中包含组名称和/或路径。通常,授权请求会根据之前发布到一些用户的客户端的 ID Token 或访问令牌来处理。如果定义,令牌必须包含此策略的声明,才能获取该用户所属的组。如果没有定义,则用户的组将从您的域配置中获取。
组
允许您选择在评估权限时此策略应强制执行的组。添加组后,您可以通过将复选框标记为 Children 来扩展对组 的子项的访问。如果保留未标记,则访问限制仅适用于所选组。
逻辑
评估完其他条件后要应用的此策略逻辑。
5.7.2. 扩展对子组的访问 复制链接链接已复制到粘贴板!
默认情况下,当您向此策略添加组时,访问限制将仅适用于所选组的成员。
在某些情况下,可能需要仅允许访问组本身,而是允许访问层次结构中的任何子组。对于任何组,您可以标记 扩展为子组的复选框,以扩展对子组的访问。
扩展对子组的访问
在上例中,策略被授予 IT 或其任何子级的任何用户成员的访问权限。
5.8. 基于客户端范围的策略 复制链接链接已复制到粘贴板!
您可以使用此类策略为允许一个或多个客户端范围访问对象的权限定义条件。
默认情况下,添加到此策略的客户端范围没有指定,如果授予了任何这些客户端范围,策略将授予访问权限。但是,如果要强制执行特定的客户端范围,您可以指定一个特定的客户端范围为 required。
要创建基于客户端范围的策略,请从策略类型列表中选择 Client Scope。
添加客户端范围策略
5.8.1. Configuration 复制链接链接已复制到粘贴板!
Name
描述该策略的人类可读和唯一字符串。最佳实践是使用与您的业务和安全要求紧密相关的名称,以便您可以更轻松地识别它们。
描述
包含此策略详情的字符串。
客户端范围
指定此策略允许哪些客户端范围。
逻辑
评估完其他条件后要应用的此策略逻辑。
5.8.2. 根据需要定义客户端范围 复制链接链接已复制到粘贴板!
在创建基于客户端范围策略时,您可以将特定的客户端范围指定为 Required。当这样做时,只有在客户端请求访问被授予了所有 required 客户端范围时才会授予访问权限。
所需的客户端范围示例
要根据需要指定客户端范围,请根据需要选择所需的客户端范围 所需的 复选框。
当您的策略定义了多个客户端范围,但只有其中的一个子集是强制使用的,则所需的客户端范围很有用。
5.9. 基于正则表达式的策略 复制链接链接已复制到粘贴板!
您可以使用这种类型的策略为您的权限定义正则表达式条件。
要创建新的基于 regex 的策略,请从策略类型列表中选择 Regex。
此策略解决了当前身份中提供的属性。
添加 Regex 策略
5.9.1. Configuration 复制链接链接已复制到粘贴板!
Name
描述该策略的人类可读和唯一字符串。最佳实践是使用与您的业务和安全要求紧密相关的名称,以便您可以更轻松地识别它们。
描述
包含此策略详情的字符串。
目标声明
指定令牌中的目标声明的名称。对于基于 JSON 的声明,您可以使用点表示法嵌套和方括号来按索引访问数组字段。例如,contact.address[0].country。如果目标声明引用 JSON 对象,则第一个路径(如
contact)应映射到包含 JSON 对象的属性名称。正则表达式模式
指定正则表达式模式。
逻辑
评估完其他条件后要应用的此策略的 Logic。
5.10. 正和负的逻辑 复制链接链接已复制到粘贴板!
可以使用正或负逻辑配置策略。简而言之,您可以使用此选项定义策略结果是否应保留下来。
例如,假设您想创建一个策略,其中只有 未 授予特定角色的用户才应被授予访问权限。在这种情况下,您可以使用该角色创建一个基于角色的策略,并将其 Logic 字段设置为 Negative。如果您 保留了,这是默认行为,则策略结果将保留原样。
5.11. 策略评估 API 复制链接链接已复制到粘贴板!
使用 JavaScript 编写基于规则的策略时,红帽构建的 Keycloak 提供了一个评估 API,它提供有用的信息来帮助确定是否应授予权限。
此 API 由几个接口组成,供您访问信息,例如
- 评估的权限,同时代表所请求的资源和范围。
- 与请求的资源关联的属性
- 运行时环境以及与执行上下文关联的任何其他属性
- 有关组成员资格和角色等用户的信息
主接口是 org.keycloak.authorization.policy.evaluation.Evaluation,它定义了以下合同:
在处理授权请求时,红帽构建的 Keycloak 会在 评估 任何策略前创建一个评估实例。然后,此实例传递到每个策略,以确定访问是 GRANT 还是 DENY。
通过对 评估 实例调用 grant () 或 deny () 方法来确定策略。默认情况下,评估 实例的状态被拒绝,这意味着您的策略必须明确调用 grant () 方法,以指示应授予的策略评估引擎。
其他资源
5.11.1. 评估上下文 复制链接链接已复制到粘贴板!
评估上下文在评估期间为策略提供有用的信息。
在这个接口中,策略可以获取:
-
经过身份验证的
身份 - 有关执行上下文和运行时环境的信息
身份 基于与授权请求一起发送的 OAuth2 访问令牌构建,此构造可以访问从原始令牌提取的所有声明。例如,如果您使用 协议映射程序 在 OAuth2 访问令牌中包含自定义声明,您也可以从策略访问此声明,并使用它来构建您的条件。
EvaluationContext 还允许您访问与执行和运行时环境相关的属性。目前,它们只是几个内置属性。
| Name | 描述 | 类型 |
|---|---|---|
| kc.time.date_time | 当前日期和时间 |
字符串.格式 |
| kc.client.network.ip_address | 客户端的 IPv4 地址 | 字符串 |
| kc.client.network.host | 客户端的主机名 | 字符串 |
| kc.client.id | 客户端 ID | 字符串 |
| kc.client.user_agent | 'User-Agent' HTTP 标头的值 | String[] |
| kc.realm.name | 域的名称 | 字符串 |
第 6 章 管理权限 复制链接链接已复制到粘贴板!
权限关联受保护的对象,以及必须接受评估的策略,以确定是否应该授予访问权限。
在创建了您要保护的资源以及您要用来保护这些资源的策略后,您可以开始管理权限。要管理权限,请在编辑资源服务器时点 Permissions 选项卡。
权限
可以创建权限来保护两个主要类型的对象:
- Resources
- 范围
要创建权限,请从权限列表右上角的 item 列表中选择您要创建的权限类型。以下小节更详细地描述了这两类对象。
6.1. 创建基于资源的权限 复制链接链接已复制到粘贴板!
基于资源的权限定义一组一个或多个资源来保护使用一个或多个授权策略。
要创建基于资源的新权限,请从创建权限下拉菜单中选择 Create resource-based 权限。
添加资源权限
6.1.1. Configuration 复制链接链接已复制到粘贴板!
Name
描述权限的人类可读和唯一字符串。最佳实践是使用与您的业务和安全要求紧密相关的名称,以便您可以更轻松地识别它们。
描述
包含此权限详情的字符串。
应用 To Resource Type
指定权限是否应用到给定类型的所有资源。选择此字段时,会提示您输入要保护的资源类型。
资源类型
定义要保护的资源类型。定义后,会为与该类型匹配的所有资源评估此权限。
Resources
定义用于保护的一个或多个资源的集合。
policy
定义与权限关联的一个或多个策略的集合。要关联策略,您可以选择现有策略,或者通过选择您要创建的策略类型来创建新策略。
决策策略
6.1.2. 类型的资源权限 复制链接链接已复制到粘贴板!
资源权限也可用于定义要应用到给定类型的所有资源的策略。当您具有共享通用访问要求和限制的资源时,这种基于资源的权限形式很有用。
通常,应用中的资源可以根据它们封装的数据或它们所提供的功能来分类(或键入)。例如,一个金融应用程序可以管理不同的银行客户,各家都属于特定客户。虽然它们是不同的银行帐户,它们共享了由银行组织全局定义的通用安全要求和约束。使用类型的资源权限,您可以定义适用于所有银行帐户的通用策略,例如:
- 只有所有者可以管理其帐户
- 只允许从所有者的国家/地区和/或区域进行访问
- 强制特定验证方法
要创建输入的资源权限,请在创建新资源权限时单击 Apply to Resource Type。当 Apply to Resource Type 设置为 On 时,您可以指定您要保护的类型以及要应用的策略来管理对指定类型的所有资源的访问。
类型的资源权限示例
6.2. 创建基于范围的权限 复制链接链接已复制到粘贴板!
基于范围的权限定义了由一个或多个范围组成的集合,以使用一个或多个授权策略集来保护。与基于资源的权限不同,您可以使用此权限类型为资源创建权限,以及与其关联的范围,在定义管理资源的权限以及可以对其执行的操作时提供更粒度。
要创建基于范围的新权限,请从 Create permissions 下拉菜单中选择 Create scope-based permissions。
添加范围权限
6.2.1. Configuration 复制链接链接已复制到粘贴板!
Name
描述权限的人类可读和唯一字符串。最佳实践是使用与您的业务和安全要求紧密相关的名称,以便您可以更轻松地识别它们。
描述
包含此权限详情的字符串。
资源
将范围限制为与所选资源关联的范围。如果没有选择任何范围,则所有范围都可用。
范围
定义用于保护的一个或多个范围的集合。
policy
定义与权限关联的一个或多个策略的集合。要关联策略,您可以选择现有策略,或者通过选择您要创建的策略类型来创建新策略。
决策策略
6.3. 策略决策策略 复制链接链接已复制到粘贴板!
将策略与权限关联时,您还可以定义一个决策策略,以指定如何评估关联策略的结果以确定访问。
unanimous
如果不提供任何策略,则默认策略。在这种情况下,所有策略都 必须评估对最终决策的积极决定。
Affirmative
在这种情况下,至少有一个 策略必须评估对最终决策的积极决定。
consensus
在这种情况下,正决策的数量必须大于负决策的数量。如果正和负决策的数量相等,最终决策将是负数。
第 7 章 评估和测试策略 复制链接链接已复制到粘贴板!
在设计策略时,您可以模拟授权请求来测试策略的评估方式。
您可以在编辑资源服务器时点 Evaluate 选项卡来访问策略评估工具。您可以指定不同的输入来模拟实际授权请求并测试策略的影响。
策略评估工具
7.1. 提供身份信息 复制链接链接已复制到粘贴板!
身份信息 过滤器可用于指定请求权限的用户。
7.2. 提供上下文信息 复制链接链接已复制到粘贴板!
上下文信息 过滤器可用于定义评估上下文的额外属性,以便策略可以获取这些相同的属性。
7.3. 授予权限 复制链接链接已复制到粘贴板!
Permissions 过滤器可用于构建授权请求。您可以为一个或多个资源和范围的集合请求权限。如果要根据所有受保护的资源和范围模拟授权请求,请单击 Add,而不指定任何 Resources 或 Scopes。
指定所需的值后,请单击 Evaluate。
第 8 章 授权服务 复制链接链接已复制到粘贴板!
红帽构建的 Keycloak 授权服务基于已知的标准构建,如 OAuth2 和用户管理的访问规格。
OAuth2 客户端(如前端应用)可以使用令牌端点从服务器获取访问令牌,并使用这些令牌来访问由资源服务器(如后端服务)保护的资源。同样,红帽构建的 Keycloak 授权服务为 OAuth2 提供扩展,以便根据处理与所请求的资源或范围关联的所有策略来发布访问令牌。这意味着资源服务器可以根据服务器授予的权限并由访问令牌来强制访问其受保护的资源。在 Red Hat build of Keycloak Authorization Services 中,带有权限的访问令牌被称为 Requesting Party Token 或 RPT。
除了 RPT 颁发外,红帽构建的 Keycloak 授权服务还提供一组 RESTful 端点,允许资源服务器管理其受保护的资源、范围、权限和策略,帮助开发人员将这些功能扩展或集成到其应用程序中,以支持精细的授权。
8.1. 发现授权服务端点和元数据 复制链接链接已复制到粘贴板!
Red Hat build of Keycloak 提供了一个发现文档,客户端可以获取所有必要的信息,以与红帽构建的 Keycloak 授权服务交互,包括端点位置和功能。
发现文档可从以下位置获取:
curl -X GET \
http://${host}:${port}/realms/${realm}/.well-known/uma2-configuration
curl -X GET \
http://${host}:${port}/realms/${realm}/.well-known/uma2-configuration
其中 ${host}:${port} 是运行 Red Hat build of Keycloak 的主机名(或 IP 地址),其中 ${realm} 是红帽构建的 Keycloak 中域的名称。
因此,您应该得到一个响应,如下所示:
每个端点都会公开一组特定的功能:
token_endpoint
支持
urn:ietf:params:oauth:grant-type:uma-ticket授权类型的 OAuth2 兼容令牌端点。通过此端点,客户端可以发送授权请求并获取 RPT,红帽构建的 Keycloak 授予的所有权限。token_introspection_endpoint
OAuth2 兼容令牌内省端点,客户端可用于查询服务器来确定 RPT 的活动状态,并确定与令牌关联的任何其他信息,如红帽构建的 Keycloak 的权限。
resource_registration_endpoint
一个与 UMA 兼容的资源注册端点,资源服务器可以使用它来管理其受保护的资源和范围。此端点提供操作创建、读取、更新和删除红帽构建的 Keycloak 中的资源和范围。
permission_endpoint
与 UMA 兼容的权限端点,资源服务器可以使用它来管理权限票据。此端点在 Red Hat build of Keycloak 中提供操作创建、读取、更新和删除权限票据。
8.2. 获取权限 复制链接链接已复制到粘贴板!
要从红帽构建的 Keycloak 获取权限,您可以将授权请求发送到令牌端点。因此,红帽构建的 Keycloak 将评估与请求的资源以及范围关联的所有策略,并使用服务器授予的所有权限发布 RPT。
客户端允许使用以下参数将授权请求发送到令牌端点:
grant_type
这个参数是必需的。必须是
urn:ietf:params:oauth:grant-type:uma-ticket。Ticket
这个参数是可选的。作为 UMA 授权过程的一部分,客户端收到的最新权限票据。
claim_token
这个参数是可选的。代表服务器在评估所请求的资源及范围的权限时应考虑的额外声明的字符串。这个参数允许客户端将声明推送到红帽构建的 Keycloak。有关所有支持的令牌格式的详情,请参阅
claim_token_format参数。claim_token_format
这个参数是可选的。指示
claim_token参数中指定的令牌格式的字符串。Red Hat build of Keycloak 支持两种令牌格式:urn:ietf:params:oauth:token-type:jwt和https://openid.net/specs/openid-connect-core-1_0.html#IDToken。urn:ietf:params:oauth:token-type:jwt格式表示claim_token参数引用访问令牌。https://openid.net/specs/openid-connect-core-1_0.html#IDToken表示claim_token参数引用 OpenID Connect ID Token。rpt
这个参数是可选的。之前发布的 RPT,其权限也应评估并添加新。这个参数允许拥有 RPT 的客户端执行按需添加权限的增量授权。
权限
这个参数是可选的。代表一个或多个资源的集合的字符串,客户端正在寻求访问的范围。可多次定义此参数,以便为多个资源和范围请求权限。这个参数是
urn:ietf:params:oauth:grant-type:uma-ticket授权类型的扩展,以允许客户端在没有权限票据的情况下发送授权请求。字符串的格式必须是:RESOURCE_ID#SCOPE_ID。例如:Resource A#Scope A,Resource A#Scope A, Scope B, Scope C,Resource A,#Scope A.permission_resource_format
这个参数是可选的。代表格式的字符串,表示
permission参数中的资源。可能的值有id和uri。id表示格式是RESOURCE_ID。URI表示格式是URI。如果没有指定,则默认为id。permission_resource_matching_uri
这个参数是可选的。指示在
permission参数中以 URI 格式表示资源时是否使用路径匹配的值。如果没有指定,则默认为 false。受众
这个参数是可选的。客户端希望访问的资源服务器的客户端标识符。如果定义了
permission参数,则此参数是必需的。它充当红帽构建的 Keycloak 的提示,以指示应评估哪些权限的上下文。response_include_resource_name
这个参数是可选的。指示资源名称是否应包含在 RPT 的权限中的布尔值。如果为 false,则只包括资源标识符。
response_permissions_limit
这个参数是可选的。整数 N,为 RPT 可以具有的权限数量定义限制。与
rpt参数一同使用时,只有最后 N 请求的权限将保存在 RPT 中。submit_request
这个参数是可选的。指明服务器是否应该创建对权限票据引用的资源和范围的权限请求的布尔值。这个参数仅在与
ticket参数一起使用作为 UMA 授权过程的一部分时才生效。response_mode
这个参数是可选的。一个字符串值,代表服务器应如何响应授权请求。当您主要对整个决策或服务器授予的权限而不是标准 OAuth2 响应具有权限时,此参数特别有用。可能的值有:
决定表示来自服务器的响应应仅通过返回具有以下格式的 JSON 来代表整个决定:
{ 'result': true }{ 'result': true }Copy to Clipboard Copied! Toggle word wrap Toggle overflow 如果授权请求没有映射到任何权限,则返回
403HTTP 状态代码。权限表示来自服务器的响应应包含服务器授予的任何权限,方法是返回具有以下格式的 JSON:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 如果授权请求没有映射到任何权限,则返回
403HTTP 状态代码。
当客户端正在寻求访问由资源服务器保护的两个资源时,授权请求示例。
当客户端正在寻求访问由资源服务器保护的任何资源和范围时,授权请求示例。注意:这不会评估所有资源的权限。相反,资源服务器拥有的资源权限(由请求用户所有),并且明确被其他所有者授予请求用户的权限。
curl -X POST \
http://${host}:${port}/realms/${realm}/protocol/openid-connect/token \
-H "Authorization: Bearer ${access_token}" \
--data "grant_type=urn:ietf:params:oauth:grant-type:uma-ticket" \
--data "audience={resource_server_client_id}"
curl -X POST \
http://${host}:${port}/realms/${realm}/protocol/openid-connect/token \
-H "Authorization: Bearer ${access_token}" \
--data "grant_type=urn:ietf:params:oauth:grant-type:uma-ticket" \
--data "audience={resource_server_client_id}"
当客户端在从资源服务器收到权限票据后访问 UMA 保护的资源时,作为授权过程的一部分,请求示例:
curl -X POST \
http://${host}:${port}/realms/${realm}/protocol/openid-connect/token \
-H "Authorization: Bearer ${access_token}" \
--data "grant_type=urn:ietf:params:oauth:grant-type:uma-ticket" \
--data "ticket=${permission_ticket}
curl -X POST \
http://${host}:${port}/realms/${realm}/protocol/openid-connect/token \
-H "Authorization: Bearer ${access_token}" \
--data "grant_type=urn:ietf:params:oauth:grant-type:uma-ticket" \
--data "ticket=${permission_ticket}
如果红帽构建的 Keycloak 评估过程造成权限不足,它会发出与权限关联的 RPT:
红帽构建的 Keycloak 使用 RPT 响应客户端
在使用其他授权类型时,来自服务器的响应就像来自令牌端点的任何其他响应一样。RPT 可以从 access_token 响应参数获得。如果客户端没有授权,红帽构建的 Keycloak 会使用 403 HTTP 状态代码进行响应:
红帽构建的 Keycloak 拒绝授权请求
8.2.1. 客户端验证方法 复制链接链接已复制到粘贴板!
客户端需要向令牌端点进行身份验证,才能获取 RPT。当使用 urn:ietf:params:oauth:grant-type:uma-ticket 授权类型时,客户端可以使用其中任何一个验证方法:
bearer Token
客户端应在 HTTP Authorization 标头中将访问令牌作为 Bearer 凭据发送到令牌端点。
示例:使用访问令牌向令牌端点进行身份验证的授权请求
curl -X POST \ http://${host}:${port}/realms/${realm}/protocol/openid-connect/token \ -H "Authorization: Bearer ${access_token}" \ --data "grant_type=urn:ietf:params:oauth:grant-type:uma-ticket"curl -X POST \ http://${host}:${port}/realms/${realm}/protocol/openid-connect/token \ -H "Authorization: Bearer ${access_token}" \ --data "grant_type=urn:ietf:params:oauth:grant-type:uma-ticket"Copy to Clipboard Copied! Toggle word wrap Toggle overflow 当客户端代表用户代表时,此方法特别有用。在这种情况下,bearer 令牌是以前由 Red Hat build of Keycloak 向某些客户端发布的访问令牌,代表用户(或代表自己负责)。将评估权限,考虑访问令牌所代表的访问上下文。例如,如果对代表用户 A 的 Client A 发出访问令牌,则根据用户 A 具有访问权限的资源和范围授予权限。
客户端凭证
客户端可以使用红帽构建的 Keycloak 支持的任何客户端验证方法。例如,client_id/client_secret 或 JWT。
示例:使用客户端 id 和 client secret 对令牌端点进行身份验证的授权请求
curl -X POST \ http://${host}:${port}/realms/${realm}/protocol/openid-connect/token \ -H "Authorization: Basic cGhvdGg6L7Jl13RmfWgtkk==pOnNlY3JldA==" \ --data "grant_type=urn:ietf:params:oauth:grant-type:uma-ticket"curl -X POST \ http://${host}:${port}/realms/${realm}/protocol/openid-connect/token \ -H "Authorization: Basic cGhvdGg6L7Jl13RmfWgtkk==pOnNlY3JldA==" \ --data "grant_type=urn:ietf:params:oauth:grant-type:uma-ticket"Copy to Clipboard Copied! Toggle word wrap Toggle overflow
8.2.2. 推送声明 复制链接链接已复制到粘贴板!
从服务器获得权限时,您可以推送任意声明,以便在评估权限时将这些声明可供您的策略使用。
如果您要在不使用权限票据(UMA 流) 的情况下 从服务器获取权限,您可以发送授权请求到令牌端点,如下所示:
claim_token 参数需要一个 BASE64 编码的 JSON,其格式类似以下示例:
{
"organization" : ["acme"]
}
{
"organization" : ["acme"]
}
格式需要一个或多个声明,每个声明的值必须是字符串数组。
8.2.2.1. 使用 UMA 推送声明 复制链接链接已复制到粘贴板!
有关如何使用 UMA 和权限票据时推送声明的更多详细信息,请参阅 权限 API
8.3. 用户管理的访问 复制链接链接已复制到粘贴板!
红帽构建的 Keycloak 授权服务基于用户管理的访问或 UMA (简称)。UMA 是一个规格,它通过以下方法增强了 OAuth2 功能:
隐私性
随着更多数据和设备可用并连接到云,用户隐私日会变得巨大的关注。对于 UMA 和 Red Hat build of Keycloak,资源服务器可以增强其功能,以便改进其资源如何保护其资源,以根据用户定义的策略授予权限。
第三方授权
资源所有者(例如:常规最终用户)可以管理对其资源的访问,并授权其他各方(例如,常规最终用户)访问这些资源。这与 OAuth2 不同,其中同意代表用户代表客户端应用程序,使用 UMA 资源所有者以完全异步的方式同意其他用户的访问权限。
资源共享
资源所有者可以管理其资源的权限,并决定谁可以访问特定资源以及如何访问。然后,Red Hat build of Keycloak 可以充当共享管理服务,资源所有者可以从中管理其资源。
红帽构建的 Keycloak 是兼容 UMA 2.0 的授权服务器,可提供大多数 UMA 功能。
例如,考虑使用互联网银行服务(资源服务器)来管理她银行帐户(资源)的用户 alice (资源所有者)。第一天,Alice 决定向 Bob (请求方)开放她的银行帐户。但是,Bob 只能具有查看(范围)vid 帐户的访问权限。
作为资源服务器,互联网银行服务必须能够保护 alice 的银行帐户。为此,它依赖红帽构建 Keycloak 资源注册端点,从而在代表 alice's bank 帐户的服务器中创建资源。
目前,如果 Bob 试图访问 alice 的银行帐户,则访问将被拒绝。互联网银行服务为银行帐户定义了几个默认策略。其中之一就是,只有所有者,在本例中为 alice,可以访问她的银行帐户。
但是,Internet 银行服务会遵守 alice 的隐私,也允许她更改银行帐户的特定策略。她可能会更改的其中一项策略是定义允许哪些人查看其银行帐户。为此,互联网银行服务依赖于红帽构建的 Keycloak 来为 alice 提供空间,其中她可以选择个人和允许访问的操作(或数据)。在任何时候,vovid 可以撤销访问权限,或向 Bob 授予其他权限。
8.3.1. 授权过程 复制链接链接已复制到粘贴板!
在 UMA 中,当客户端尝试访问 UMA 保护的资源服务器时,授权过程会启动。
UMA 保护的资源服务器在请求中需要一个 bearer 令牌,其中令牌是 RPT。当客户端在没有 RPT 的情况下在资源服务器上请求资源时:
客户端请求受保护的资源,而不发送 RPT
curl -X GET \
http://${host}:${port}/my-resource-server/resource/1bfdfe78-a4e1-4c2d-b142-fc92b75b986f
curl -X GET \
http://${host}:${port}/my-resource-server/resource/1bfdfe78-a4e1-4c2d-b142-fc92b75b986f
资源服务器将响应发送回带有权限 票据 的客户端,以及红帽构建的 Keycloak 服务器的位置的 as_uri 参数,以便获取 RPT。
资源服务器使用权限票据响应
HTTP/1.1 401 Unauthorized
WWW-Authenticate: UMA realm="${realm}",
as_uri="https://${host}:${port}/realms/${realm}",
ticket="016f84e8-f9b9-11e0-bd6f-0021cc6004de"
HTTP/1.1 401 Unauthorized
WWW-Authenticate: UMA realm="${realm}",
as_uri="https://${host}:${port}/realms/${realm}",
ticket="016f84e8-f9b9-11e0-bd6f-0021cc6004de"
权限票据是红帽构建的 Keycloak 权限 API 发布的特殊类型的令牌。它们表示正在请求的权限(例如:资源和范围)以及与请求关联的任何其他信息。只有资源服务器才能创建这些令牌。
现在,客户端有权限票据,以及红帽构建的 Keycloak 服务器的位置,客户端可以使用发现文档来获取令牌端点的位置并发送授权请求。
客户端向令牌端点发送授权请求,以获取 RPT
curl -X POST \
http://${host}:${port}/realms/${realm}/protocol/openid-connect/token \
-H "Authorization: Bearer ${access_token}" \
--data "grant_type=urn:ietf:params:oauth:grant-type:uma-ticket" \
--data "ticket=${permission_ticket}
curl -X POST \
http://${host}:${port}/realms/${realm}/protocol/openid-connect/token \
-H "Authorization: Bearer ${access_token}" \
--data "grant_type=urn:ietf:params:oauth:grant-type:uma-ticket" \
--data "ticket=${permission_ticket}
如果红帽构建的 Keycloak 评估过程造成权限不足,它会发出与权限关联的 RPT:
红帽构建的 Keycloak 使用 RPT 响应客户端
在使用其他授权类型时,来自服务器的响应就像来自令牌端点的任何其他响应一样。RPT 可以从 access_token 响应参数获得。如果客户端没有授权红帽构建的 Keycloak 权限,使用 403 HTTP 状态代码进行响应:
红帽构建的 Keycloak 拒绝授权请求
8.3.2. 提交权限请求 复制链接链接已复制到粘贴板!
作为授权过程的一部分,客户端需要首先从 UMA 保护的资源服务器获取权限票据,以便在红帽构建的 Keycloak Token Endpoint 中使用 RPT 进行交换。
默认情况下,红帽构建的 Keycloak 会以 403 HTTP 状态代码和 request_denied 错误(如果客户端无法使用 RPT )进行响应。
红帽构建的 Keycloak 拒绝授权请求
此类响应意味着红帽构建的 Keycloak 无法发布 RPT,其权限由权限票据表示。
在某些情况下,客户端应用程序可能希望启动异步授权流,并让请求的资源所有者决定是否应授予访问权限。为此,客户端可以使用 submit_request 请求参数以及对令牌端点的授权请求:
使用 submit_request 参数时,红帽构建的 Keycloak 将为每个访问失败的资源保留权限请求。创建后,资源所有者可以检查其帐户并管理其权限请求。
您可以将此功能视为应用程序中的 请求访问 按钮,用户可以向其他用户询问其他用户访问其资源。
8.3.3. 管理对用户资源的访问 复制链接链接已复制到粘贴板!
用户可以使用红帽构建的 Keycloak 帐户控制台来管理对其资源的访问。要启用此功能,您必须首先为您的域启用用户管理的访问。
流程
- 登录管理控制台。
- 单击菜单中的 Realm Settings。
- 将 用户管理的访问切换为 ON。
单击 Admin Console 右上角的用户名,再选择 Manage Account。
单击菜单选项中的 My Resources。将显示带有以下选项的页面。
管理 我的资源
本节包含由用户拥有的所有资源的列表。用户可以单击资源以了解更多详细信息,并与其他资源共享。当权限请求是等待批准时,会在资源名称旁边放置一个图标。这些请求连接到请求访问特定资源的各方(用户)。允许用户批准或拒绝这些请求。您可以点击图标完成此操作
管理与我共享的资源
本节包含与用户共享的所有资源的列表。
通过访问此资源来管理人员
本节包含有权访问此资源的人员的列表。用户可以通过单击
Revoke按钮或删除特定的权限来撤销访问权限。与其他人共享资源
通过输入其他用户的用户名或电子邮件,用户可以共享该资源,然后选择他想要授予访问权限的权限。
8.4. 保护 API 复制链接链接已复制到粘贴板!
Protection API 提供了一组与 UMA 兼容的端点,提供:
资源管理
使用这个端点,资源服务器可以远程管理其资源,并使策略强制 器查询服务器以获取需要保护的资源。
权限管理
在 UMA 协议中,资源服务器访问此端点以创建权限票据。Red Hat build of Keycloak 还提供端点来管理权限和查询权限的状态。
Policy API
Red Hat build of Keycloak 利用 UMA Protection API 来允许资源服务器为其用户管理权限。除了 Resource 和 Permission API 外,红帽构建的 Keycloak 还提供了一个 Policy API,其中可通过资源服务器代表其用户将权限设置为资源。
此 API 的一个重要要求是 只允许 资源服务器使用称为保护 API 令牌(PAT)的特殊 OAuth2 访问令牌来访问其端点。在 UMA 中,PAT 是范围为 uma_protection 的令牌。
8.4.1. 什么是 PAT 以及如何获取它 复制链接链接已复制到粘贴板!
保护 API 令牌 (PAT)是一个特殊的 OAuth2 访问令牌,范围定义为 uma_protection。当您创建资源服务器时,Red Hat build of Keycloak 会自动为对应的客户端应用程序创建一个角色 uma_protection,并将其与客户端的服务帐户相关联。
使用 uma_protection 角色授予的服务帐户
资源服务器可以从红帽构建的 Keycloak 获取 PAT,就像任何其他 OAuth2 访问令牌一样。例如,使用 curl:
curl -X POST \
-H "Content-Type: application/x-www-form-urlencoded" \
-d 'grant_type=client_credentials&client_id=${client_id}&client_secret=${client_secret}' \
"http://${host}:${port}/realms/${realm_name}/protocol/openid-connect/token"
curl -X POST \
-H "Content-Type: application/x-www-form-urlencoded" \
-d 'grant_type=client_credentials&client_id=${client_id}&client_secret=${client_secret}' \
"http://${host}:${port}/realms/${realm_name}/protocol/openid-connect/token"
上面的例子是使用 client_credentials 授权类型从服务器获取 PAT。因此,服务器会返回类似如下的响应:
红帽构建的 Keycloak 可以不同的方式验证您的客户端应用程序。为了简单起见,这里使用 client_credentials 授权类型,这需要 client_id 和 client_secret。您可以选择使用任何支持的身份验证方法。
8.4.2. 管理资源 复制链接链接已复制到粘贴板!
资源服务器可以使用 UMA 兼容端点远程管理其资源。
http://${host}:${port}/realms/${realm_name}/authz/protection/resource_set
http://${host}:${port}/realms/${realm_name}/authz/protection/resource_set
此端点提供概述的操作(明确省略的路径):
- 创建资源设置描述:POST /resource_set
- 读取资源集描述:GET /resource_set/{_id}
- 更新资源设置描述:PUT /resource_set/{_id}
- 删除资源设置描述:DELETE /resource_set/{_id}
- 列出资源设置描述:GET /resource_set
有关这些操作的合同的更多信息,请参阅 UMA 资源注册 API。
8.4.2.1. 创建资源 复制链接链接已复制到粘贴板!
要创建资源,您必须发送 HTTP POST 请求,如下所示:
默认情况下,资源的所有者是资源服务器。如果要定义不同的所有者,如特定用户,您可以发送如下请求:
其中可使用用户名或用户的标识符来设置属性 所有者。
8.4.2.2. 创建用户管理的资源 复制链接链接已复制到粘贴板!
默认情况下,通过保护 API 创建的资源无法通过 帐户控制台 由资源所有者管理。
要创建资源并允许资源所有者管理这些资源,您必须设置 ownerManagedAccess 属性,如下所示:
8.4.2.3. 更新资源 复制链接链接已复制到粘贴板!
要更新现有资源,请发送 HTTP PUT 请求,如下所示:
8.4.2.4. 删除资源 复制链接链接已复制到粘贴板!
要删除现有资源,请发送 HTTP DELETE 请求,如下所示:
curl -v -X DELETE \
http://${host}:${port}/realms/${realm_name}/authz/protection/resource_set/{resource_id} \
-H 'Authorization: Bearer '$pat
curl -v -X DELETE \
http://${host}:${port}/realms/${realm_name}/authz/protection/resource_set/{resource_id} \
-H 'Authorization: Bearer '$pat
8.4.2.5. 查询资源 复制链接链接已复制到粘贴板!
要通过 id 查询资源,请发送 HTTP GET 请求,如下所示:
http://${host}:${port}/realms/${realm_name}/authz/protection/resource_set/{resource_id}
http://${host}:${port}/realms/${realm_name}/authz/protection/resource_set/{resource_id}
要查询给定名称的资源,请发送 HTTP GET 请求,如下所示:
http://${host}:${port}/realms/${realm_name}/authz/protection/resource_set?name=Alice Resource
http://${host}:${port}/realms/${realm_name}/authz/protection/resource_set?name=Alice Resource
默认情况下,名称 过滤器将匹配具有给定模式的任何资源。要将查询限制为只返回具有完全匹配的资源,请使用:
http://${host}:${port}/realms/${realm_name}/authz/protection/resource_set?name=Alice Resource&exactName=true
http://${host}:${port}/realms/${realm_name}/authz/protection/resource_set?name=Alice Resource&exactName=true
要查询给定的 uri 资源,请发送 HTTP GET 请求,如下所示:
http://${host}:${port}/realms/${realm_name}/authz/protection/resource_set?uri=/api/alice
http://${host}:${port}/realms/${realm_name}/authz/protection/resource_set?uri=/api/alice
要查询 所有者 的资源,请发送 HTTP GET 请求,如下所示:
http://${host}:${port}/realms/${realm_name}/authz/protection/resource_set?owner=alice
http://${host}:${port}/realms/${realm_name}/authz/protection/resource_set?owner=alice
要查询给定类型的资源,请发送 HTTP GET 请求,如下所示:
http://${host}:${port}/realms/${realm_name}/authz/protection/resource_set?type=albums
http://${host}:${port}/realms/${realm_name}/authz/protection/resource_set?type=albums
要查询给定范围的资源,请发送 HTTP GET 请求,如下所示:
http://${host}:${port}/realms/${realm_name}/authz/protection/resource_set?scope=read
http://${host}:${port}/realms/${realm_name}/authz/protection/resource_set?scope=read
当查询服务器以获取权限时,首先使用 参数,最大 结果来限制结果。
8.4.3. 管理权限请求 复制链接链接已复制到粘贴板!
使用 UMA 协议的资源服务器可以使用特定的端点来管理权限请求。此端点提供了一个与 UMA 兼容的流,用于注册权限请求并获取一个权限票据。
http://${host}:${port}/realms/${realm_name}/authz/protection/permission
http://${host}:${port}/realms/${realm_name}/authz/protection/permission
权限票据 是代表权限请求的特殊安全令牌类型。根据 UMA 规格,权限票据是:
关联处理从授权服务器到资源服务器,从资源服务器到客户端,最终从客户端重新发送到授权服务器,以便授权服务器评估正确的策略以应用到授权数据的请求。
在大多数情况下,您不需要直接处理此端点。Red Hat build of Keycloak 提供了一个 策略强制器,为资源服务器启用 UMA,以便它可以从授权服务器获取权限票据,将这个票据返回到客户端应用程序,并根据最终请求方令牌(RPT)强制执行授权决策。
从红帽构建的 Keycloak 获取权限票据的过程由资源服务器执行,而不是常规客户端应用程序,当客户端试图访问受保护的资源时获得权限票据,而无需必要授予访问该资源。使用 UMA 时,权限票据的颁发是允许资源服务器进行的重要方面:
- 从与资源服务器保护的资源关联的数据摘要
- 在 Red Hat build of Keycloak 授权请求中注册,稍后可以在工作流中使用它们来根据资源的所有者同意授予访问权限
- 将资源服务器与授权服务器分离,并允许它们使用不同的授权服务器保护和管理其资源
客户而言,权限票据也很重要的方面,需要强调:
- 客户端不需要了解授权数据如何与受保护的资源关联。对客户端的权限票据完全不透明。
- 客户端可以访问不同资源服务器上的资源,并由不同的授权服务器保护
这些只是 UMA 带来的一些好处,其中 UMA 的其他方面基于权限票据,特别关注隐私和用户对其资源的控制访问权限。
8.4.3.1. 创建权限票据 复制链接链接已复制到粘贴板!
要创建权限票据,请发送 HTTP POST 请求,如下所示:
在创建票据时,您还可以推送任意声明,并将这些声明与 ticket 关联:
在评估与权限票据关联的资源和范围的权限时,策略可以使用这些声明。
8.4.3.2. 其他非与 UMA 兼容的端点 复制链接链接已复制到粘贴板!
8.4.3.2.1. 创建权限票据 复制链接链接已复制到粘贴板!
要将 ID 为 {resource_id} 的特定资源的权限授予 ID {user_id} 的用户,作为资源的所有者发送 HTTP POST 请求,如下所示:
8.4.3.2.2. 获取权限票据 复制链接链接已复制到粘贴板!
curl http://${host}:${port}/realms/${realm_name}/authz/protection/permission/ticket \
-H 'Authorization: Bearer '$access_token
curl http://${host}:${port}/realms/${realm_name}/authz/protection/permission/ticket \
-H 'Authorization: Bearer '$access_token
您可以使用这些查询参数:
-
scopeId -
resourceId -
owner -
requester -
已授予 -
returnNames -
first -
max
8.4.3.2.3. 更新权限票据 复制链接链接已复制到粘贴板!
8.4.3.2.4. 删除权限票据 复制链接链接已复制到粘贴板!
curl -X DELETE http://${host}:${port}/realms/${realm_name}/authz/protection/permission/ticket/{ticket_id} \
-H 'Authorization: Bearer '$access_token
curl -X DELETE http://${host}:${port}/realms/${realm_name}/authz/protection/permission/ticket/{ticket_id} \
-H 'Authorization: Bearer '$access_token
8.4.4. 使用 Policy API 管理资源权限 复制链接链接已复制到粘贴板!
Red Hat build of Keycloak 利用 UMA Protection API 来允许资源服务器为其用户管理权限。除了 Resource 和 Permission API 外,红帽构建的 Keycloak 还提供了一个 Policy API,其中可通过资源服务器代表其用户将权限设置为资源。
Policy API 位于:
http://${host}:${port}/realms/${realm_name}/authz/protection/uma-policy/{resource_id}
http://${host}:${port}/realms/${realm_name}/authz/protection/uma-policy/{resource_id}
此 API 由 bearer 令牌保护,该令牌必须代表用户对资源服务器授予的同意,才能代表其代表其管理权限。bearer 令牌可以是从令牌端点获取的常规访问令牌:
- 资源所有者密码凭证授予类型
- 令牌交换,为使用者是资源服务器的令牌交换给某些客户端(公共客户端)的访问令牌
8.4.4.1. 将权限与资源关联 复制链接链接已复制到粘贴板!
要将权限与特定资源关联,您必须发送 HTTP POST 请求,如下所示:
在上例中,我们正在创建新权限并将其关联到由 resource_id 代表的资源,其中任何拥有角色 people-manager 的用户都应 授予读取 范围。
您还可以使用其他访问控制机制创建策略,比如使用组:
或者特定的客户端:
甚至使用 JavaScript 的自定义策略:
也可以设置这些访问控制机制的任意组合。
要更新现有权限,请发送 HTTP PUT 请求,如下所示:
8.4.4.2. 删除权限 复制链接链接已复制到粘贴板!
要删除与资源关联的权限,请发送 HTTP DELETE 请求,如下所示:
curl -X DELETE \
http://localhost:8180/realms/photoz/authz/protection/uma-policy/{permission_id} \
-H 'Authorization: Bearer '$access_token
curl -X DELETE \
http://localhost:8180/realms/photoz/authz/protection/uma-policy/{permission_id} \
-H 'Authorization: Bearer '$access_token
8.4.4.3. 查询权限 复制链接链接已复制到粘贴板!
要查询与资源关联的权限,请发送 HTTP GET 请求,如下所示:
http://${host}:${port}/realms/${realm}/authz/protection/uma-policy?resource={resource_id}
http://${host}:${port}/realms/${realm}/authz/protection/uma-policy?resource={resource_id}
要查询给定名称的权限,请发送 HTTP GET 请求,如下所示:
http://${host}:${port}/realms/${realm}/authz/protection/uma-policy?name=Any people manager
http://${host}:${port}/realms/${realm}/authz/protection/uma-policy?name=Any people manager
要查询与特定范围关联的权限,请发送 HTTP GET 请求,如下所示:
http://${host}:${port}/realms/${realm}/authz/protection/uma-policy?scope=read
http://${host}:${port}/realms/${realm}/authz/protection/uma-policy?scope=read
要查询所有权限,请发送 HTTP GET 请求,如下所示:
http://${host}:${port}/realms/${realm}/authz/protection/uma-policy
http://${host}:${port}/realms/${realm}/authz/protection/uma-policy
当查询服务器以获取权限时,首先使用 参数,最大 结果来限制结果。
8.5. 请求方令牌 复制链接链接已复制到粘贴板!
请求方令牌 (RPT) 是使用 JSON web signature (JWS) 进行了数字签名的 JSON web token (JWT)。令牌基于之前由红帽构建的 Keycloak 签发的 OAuth2 访问令牌构建,代表用户或代表用户或自己使用。
当您解码 RPT 时,您会看到类似如下的有效负载:
在此令牌中,您可以从 权限 声明中获取服务器授予的所有权限。
另请注意,权限直接与您保护的资源/范围相关联,并将其与用于实际授予和发出相同权限的访问控制方法完全分离。
8.5.1. 内省请求方令牌 复制链接链接已复制到粘贴板!
有时,您可能希望内省一个请求方令牌(RPT),以检查其有效期,或在令牌中获取权限,以对资源服务器端执行授权决策。
令牌内省可帮助您实现两种主要用例:
- 当客户端应用程序需要查询令牌有效期时,以获取具有相同或额外权限的一个新令牌
- 在资源服务器端 强制实施授权决策时,特别是在没有内置策略强制适合 应用程序时
8.5.2. 获取有关 RPT 的信息 复制链接链接已复制到粘贴板!
令牌内省基本上是一个 OAuth2 令牌内省与端点,您可以从中获取有关 RPT 的信息。
http://${host}:${port}/realms/${realm_name}/protocol/openid-connect/token/introspect
http://${host}:${port}/realms/${realm_name}/protocol/openid-connect/token/introspect
要使用此端点内省 RPT,您可以向服务器发送请求,如下所示:
curl -X POST \
-H "Authorization: Basic aGVsbG8td29ybGQtYXV0aHotc2VydmljZTpzZWNyZXQ=" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d 'token_type_hint=requesting_party_token&token=${RPT}' \
"http://localhost:8080/realms/hello-world-authz/protocol/openid-connect/token/introspect"
curl -X POST \
-H "Authorization: Basic aGVsbG8td29ybGQtYXV0aHotc2VydmljZTpzZWNyZXQ=" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d 'token_type_hint=requesting_party_token&token=${RPT}' \
"http://localhost:8080/realms/hello-world-authz/protocol/openid-connect/token/introspect"
上面的请求使用 HTTP BASIC,并传递客户端的凭据(客户端 ID 和机密),以验证尝试内省令牌的客户端,但您可以使用红帽构建的 Keycloak 支持的任何其他客户端验证方法。
内省端点需要两个参数:
token_type_hint
使用 request_party_token 作为此参数的值,这表示您要内省 RPT。
token
在授权过程中,使用令牌字符串作为此参数的值,由服务器在授权过程中返回。
因此,服务器响应:
如果 RPT 未激活,则返回这个响应:
{
"active": false
}
{
"active": false
}
8.5.3. 每次我想要内省 RPT 时,我是否需要调用服务器? 复制链接链接已复制到粘贴板!
否。就像红帽构建的 Keycloak 服务器发布的常规访问令牌一样,RPT 还使用 JSON Web 令牌(JWT)规格作为默认格式。
如果要在不调用远程内省端点的情况下验证这些令牌,您可以解码 RPT 并在本地查询其有效。解码令牌后,您还可以使用令牌中的权限来强制实施授权决策。
这基本上是策略强制器的作用。确保:
- 验证 RPT 的签名(基于域的公钥)
- 基于它的 exp, iat, 和 aud 声明来查询令牌的有效性。
第 9 章 策略强制器 复制链接链接已复制到粘贴板!
策略强制点(PEP)是一种设计模式,因此您可以以不同的方式实施它。Red Hat build of Keycloak 提供了为不同平台、环境和编程语言实施 PEP 所需的所有方法。红帽构建的 Keycloak 授权服务提供 RESTful API,并利用 OAuth2 授权功能来使用集中式授权服务器进行精细授权。
红帽构建的 Keycloak 提供的 Policy enforcers 是:
- Java 策略强制 器 - 用于 Java 客户端应用程序
- JavaScript 策略强制器 -可用于红帽构建 Keycloak Javascript 适配器的应用程序中
9.1. Policy Enforcer 的 JavaScript 集成 复制链接链接已复制到粘贴板!
Red Hat build of Keycloak Server 附带一个 JavaScript 库,可用于与受策略强制器保护的资源服务器交互。这个库基于红帽构建的 Keycloak JavaScript 适配器,它可以集成,以便您的客户端从红帽构建的 Keycloak Server 获取权限。
您可以通过从 NPM 安装来获取此库:
npm install keycloak-js
npm install keycloak-js
接下来,您可以创建 KeycloakAuthorization 实例,如下所示:
keycloak-js/authz 库提供两个主要功能:
- 如果您要访问 UMA 保护的资源服务器,请使用权限票据从服务器获取权限。
- 通过发送应用程序想要访问的资源和范围从服务器获取权限。
在这两种情况下,库都允许您与资源服务器和红帽构建的 Keycloak 授权服务轻松交互,以获取具有您客户端的权限的令牌,作为 bearer 令牌来访问资源服务器上的受保护的资源。
9.1.1. 处理来自 UMA 提供的资源服务器的授权响应 复制链接链接已复制到粘贴板!
如果资源服务器受策略强制器保护,它会根据与 bearer 令牌一起执行的权限响应客户端请求。通常,当您尝试使用没有权限访问保护的资源的 bearer 令牌访问资源服务器时,资源服务器会以 401 状态代码和 WWW-Authenticate 标头响应。
HTTP/1.1 401 Unauthorized
WWW-Authenticate: UMA realm="${realm}",
as_uri="https://${host}:${port}/realms/${realm}",
ticket="016f84e8-f9b9-11e0-bd6f-0021cc6004de"
HTTP/1.1 401 Unauthorized
WWW-Authenticate: UMA realm="${realm}",
as_uri="https://${host}:${port}/realms/${realm}",
ticket="016f84e8-f9b9-11e0-bd6f-0021cc6004de"
如需更多信息,请参阅 UMA 授权过程。
您的客户端需要执行的操作是从资源服务器返回的 标头中提取权限票据,并使用库发送授权请求,如下所示:
WWW-Authenticate
授权 功能是完全异步的,支持几个回调功能来接收来自服务器的通知:
-
onGrant:函数的第一个参数。如果授权成功,并且服务器返回带有请求权限的 RPT,则回调会收到 RPT。 -
onDeny: 函数的第二个参数。只有服务器拒绝授权请求时调用。 -
onError:函数的第三个参数。只有服务器意外响应时才会调用。
大多数应用程序都应该使用 onGrant 回调在 401 响应后重试请求。后续请求应包括 RPT 作为用于重试的 bearer 令牌。
9.1.2. 获取权利 复制链接链接已复制到粘贴板!
keycloak-js/authz 库提供了一个 授权 功能,您可以通过提供客户端要访问的资源和范围从服务器获取 RPT。
有关如何获取具有用户可以访问的所有资源和范围权限的 RPT 的示例
authorization.entitlement("my-resource-server-id").then((rpt) => {
// onGrant callback function.
// If authorization was successful you'll receive an RPT
// with the necessary permissions to access the resource server
});
authorization.entitlement("my-resource-server-id").then((rpt) => {
// onGrant callback function.
// If authorization was successful you'll receive an RPT
// with the necessary permissions to access the resource server
});
有关如何获取带有特定资源和范围权限的 RPT 的示例
使用 授权 功能时,您必须提供您要访问的资源服务器的 client_id。
权利 功能是完全异步的,支持一些回调功能来接收来自服务器的通知:
-
onGrant:函数的第一个参数。如果授权成功,并且服务器返回带有请求权限的 RPT,则回调会收到 RPT。 -
onDeny: 函数的第二个参数。只有服务器拒绝授权请求时调用。 -
onError:函数的第三个参数。只有服务器意外响应时才会调用。
9.1.3. 授权请求 复制链接链接已复制到粘贴板!
授权 和授权 功能都接受授权请求对象。这个对象可使用以下属性设置:
权限
代表资源和范围的对象数组。例如:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow metadata
其属性定义服务器应如何处理授权请求的对象。
response_include_resource_name
如果资源名称应包含在 RPT 的权限中,则向服务器指示的布尔值。如果为 false,则只包括资源标识符。
response_permissions_limit
整数 N,为 RPT 可以具有的权限数量定义限制。与
rpt参数一同使用时,只有最后 N 请求的权限将保存在 RPT 中
submit_request
指明服务器是否应该创建对权限票据引用的资源和范围的权限请求的布尔值。这个参数仅在与
ticket参数一起使用作为 UMA 授权过程的一部分时生效。
9.1.4. 获取 RPT 复制链接链接已复制到粘贴板!
如果您已使用库提供的任何授权功能获取 RPT,您可以始终从授权对象获取 RPT (假设它已由前面显示的其中一个技术初始化):
const rpt = authorization.rpt;
const rpt = authorization.rpt;