概述

Keycloak支持细粒度的授权策略,并且能够组合不同的访问控制 机制,例如:

  • 基于属性的访问控制 (ABAC)

  • 基于角色的访问控制 (RBAC)

  • 基于用户的访问控制 (UBAC)

  • 基于上下文的访问控制 (CBAC)

  • 基于规则的访问控制

    • 使用JavaScript

  • 基于时间的访问控制

  • 通过策略提供者服务提供者接口 (SPI) 支持自定义访问控制机制 (ACMs)

Keycloak基于一组管理UIs和一个RESTful API,并提供了创建权限的必要手段 对于受保护的资源和范围,将这些权限与授权策略相关联,并在应用程序和服务中强制执行授权决策。

资源服务器 (服务于受保护资源的应用程序或服务) 通常依赖某种信息来决定是否应授予对受保护资源的访问权限。 对于基于RESTful的资源服务器,该信息通常是从安全令牌获得的,通常在对服务器的每个请求中作为承载令牌发送。 对于依赖于会话对用户进行身份验证的web应用程序,该信息通常存储在用户的会话中,并针对每个请求从那里检索。

通常,资源服务器仅基于基于角色的访问控制 (RBAC) 执行授权决策,其中,授予试图访问受保护资源的用户的角色会根据映射到这些相同资源的角色进行检查。 虽然角色非常有用并且被应用程序使用,但它们也有一些限制:

  • 资源和角色是紧密耦合的,对角色的更改 (例如添加,删除或更改访问上下文) 可能会影响多个资源

  • 对安全要求的更改可能意味着对应用程序代码进行深度更改以反映这些更改

  • 根据您的应用程序大小,角色管理可能会变得困难且容易出错

  • 它不是最灵活的访问控制机制。 角色不代表您是谁,并且缺乏上下文信息。 如果您已被授予角色,则您至少有一些访问权限。

考虑到今天我们需要考虑异构环境,其中用户分布在不同的区域,具有不同的本地策略, 使用不同的设备,并且对信息共享的需求很高,Keycloak授权服务可以通过提供以下服务来帮助您提高应用程序和服务的授权能力:

  • 使用细粒度授权策略和不同访问控制机制的资源保护

  • 集中资源、权限和策略管理

  • 集中式策略决策点

  • 基于一组基于REST的授权服务的REST安全性

  • 授权工作流和用户管理访问

  • 该基础结构可帮助避免跨项目 (和重新部署) 的代码复制,并快速适应安全需求的变化。

建筑

Keycloak AuthZ架构概述

从设计的角度来看,授权服务基于一组定义明确的授权模式,提供以下功能:

  • 政策管理点 (PAP)

    提供一组基于Keycloak管理控制台的UIs,用于管理资源服务器、资源、范围、权限和策略。 其中一部分也是通过使用保护API

  • 策略决策点 (PDP)

    提供可分发的策略决策点,用于发送授权请求的位置,并根据请求的权限对策略进行相应的评估。 有关更多信息,请参见获取权限

  • 政策执行点 (PEP)

    为不同的环境提供实现,以在资源服务器端实际执行授权决策。 Keycloak提供了一些内置的政策执行者

  • 策略信息点 (PIP)

    基于Keycloak Authentication Server,您可以在评估授权策略时从identies和运行时环境中获取属性。

授权过程

三个主要过程定义了必要的步骤,以了解如何使用Keycloak为您的应用程序启用细粒度授权:

  • 资源管理

  • 权限和策略管理

  • 政策执行

资源管理

资源管理涉及定义受保护内容的所有必要步骤。

资源管理概述

首先,您需要指定要保护的Keycloak,它通常表示一个web应用程序或一组一个或多个服务。 有关资源服务器的更多信息,请参见术语

资源服务器使用Keycloak管理控制台进行管理。 在那里,您可以将任何注册的客户端应用程序启用为资源服务器,并开始管理要保护的资源和范围。

资源服务器概述

资源可以是网页、RESTFul资源、文件系统中的文件、EJB等。 它们可以表示一组资源 (就像Java中的类一样),也可以表示单个特定的资源。

例如,你可能有一个银行账户表示所有银行账户的资源,并使用它来定义所有银行账户共有的授权策略。 但是,您可能希望为爱丽丝账户(属于客户的资源实例),其中仅允许所有者访问某些信息或执行操作。

可以使用Keycloak管理控制台或保护API。 在后一种情况下,资源服务器能够远程管理其资源。

作用域通常表示可以在资源上执行的操作,但不仅限于此。 您还可以使用作用域来表示资源中的一个或多个属性。

权限和策略管理

定义资源服务器和要保护的所有资源后,必须设置权限和策略。

此过程涉及所有必要的步骤,以实际定义管理资源的安全性和访问要求。

权限和策略管理概述

策略定义了访问或执行对某物 (资源或范围) 的操作必须满足的条件,但它们与所保护的内容无关。 它们是通用的,可以重用以构建权限或甚至更复杂的策略。

例如,为了仅允许授予角色 “User Premium” 的用户访问一组资源,可以使用RBAC (基于角色的访问控制)。

Keycloak提供了一些内置的策略类型 (及其各自的策略提供程序),涵盖了最常见的访问控制机制。 您甚至可以根据使用JavaScript编写的规则创建策略。

定义策略后,就可以开始定义权限了。 权限与他们正在保护的资源相结合。 在这里您指定 您想要保护的内容 (资源或范围) 以及授予或拒绝权限必须满足的策略。

政策执行

政策执行涉及实际向资源服务器强制执行授权决策的必要步骤。 这是通过使政策执行点或者PEP在能够与授权服务器通信的资源服务器,请求授权数据,并根据服务器返回的决策和权限控制对受保护资源的访问。

PEP概述

Keycloak提供了一些内置的政策执行者您可以用来保护应用程序的实现,具体取决于它们运行的平台。

授权服务

授权服务由以下RESTFul端点组成:

  • 令牌端点

  • 资源管理端点

  • 权限管理端点

这些服务中的每一个都提供了一个特定的API,涵盖了授权过程中涉及的不同步骤。

令牌端点

OAuth2客户端 (如前端应用程序) 可以使用令牌端点从服务器获取访问令牌,并使用 这些相同的令牌来访问受资源服务器保护的资源 (例如后端服务)。 同样, Keycloak授权服务为OAuth2提供扩展,以允许根据处理情况发布访问令牌 与所请求的资源或范围相关联的所有策略。 这意味着资源服务器可以强制访问 根据服务器授予并由访问令牌持有的权限,对其受保护的资源。 在密钥斗篷授权服务中 具有权限的访问令牌称为请求方令牌或简称RPT。

有关更多信息,请参见获取权限

保护API

保护API是一组符合UMA的端点-提供操作 对于资源服务器,以帮助他们管理与其关联的资源、范围、权限和策略。 只允许资源服务器访问此API,这也需要 Uma_ 保护范围。

保护API提供的操作可以分为两个主要组:

  • 资源管理

    • 创建资源

    • 删除资源

    • 按Id查找

    • 查询

  • 权限管理

    • 颁发许可票

默认情况下,启用远程资源管理。 您可以使用Keycloak管理控制台进行更改,并且仅允许通过控制台进行资源管理。

在使用UMA协议时,Protection API对权限单的发放是整个授权过程的重要组成部分。 如后续部分所述,它们表示客户端正在请求的权限,并将其发送到服务器以获取最终令牌,该令牌具有在评估与所请求的资源和范围相关联的权限和策略期间授予的所有权限。

有关更多信息,请参见保护API

术语

在进一步讨论之前,重要的是要了解Keycloak Authorization Services引入的这些术语和概念。

资源服务器

根据OAuth2术语,资源服务器是托管受保护资源并能够接受和响应受保护资源请求的服务器。

资源服务器通常依靠某种信息来决定是否应授予对受保护资源的访问权限。 对于基于RESTful的资源服务器, 该信息通常包含在安全令牌中,通常与对服务器的每个请求一起作为承载令牌发送。 依赖于会话的Web应用程序 身份验证用户通常将该信息存储在用户的会话中,并从那里为每个请求检索该信息。

穿着Keycloak,任何机密客户端应用程序可以充当资源服务器。 此客户端的资源及其各自的范围受一组授权策略的保护和管理。

资源

资源是应用程序和组织资产的一部分。 它可以是一个或多个端点的集合,一个经典的web资源 (例如HTML页面) 等等。 在授权策略术语中,资源是对象受到保护。

每个资源都有一个唯一的标识符,可以表示单个资源或一组资源。 例如,您可以管理一个银行账户资源代表并定义了所有银行帐户的一组授权策略。 但是你也可以有一个不同的资源,名为爱丽丝的银行账户,表示单个客户拥有的单个资源,该资源可以具有自己的一组授权策略。

范围

资源的范围是可以对资源执行的有限访问范围。 在授权策略术语中,范围是潜在的许多动词可以逻辑地应用于资源。

它通常表示使用给定的资源可以做什么。 作用域的示例有视图、编辑、删除等。 但是,范围也可以与资源提供的特定信息相关。 在这种情况下,您可以拥有项目资源和成本范围,其中成本范围用于定义用户访问项目成本的特定策略和权限。

权限

考虑一下这个简单且非常常见的权限:

权限将受保护的对象与必须评估以确定是否授予访问权限的策略相关联。

  • X可以做Y论资源Z

    • 哪里…

      • X表示一个或多个用户、角色或组,或它们的组合。 您也可以在这里使用声明和上下文。

      • Y表示要执行的操作,例如write、view等。

      • Z表示受保护的资源,例如 “/accounts”。

Keycloak提供了一个丰富的平台,用于构建从简单到非常复杂的基于规则的动态权限的权限策略。 它提供了灵活性,并有助于:

  • 降低代码重构和权限管理成本

  • 支持更灵活的安全模型,帮助您轻松适应安全需求的变化

  • 在运行时进行更改; 应用程序只关心受保护的资源和范围,而不是如何保护它们。

政策

策略定义了授予对象访问权限必须满足的条件。 与权限不同,您不指定受保护的对象 而是访问给定对象 (例如,资源,范围或两者) 必须满足的条件。 策略与可用于保护资源的不同访问控制机制 (acm) 密切相关。 通过策略,您可以实现基于属性的访问控制 (ABAC) 、基于角色的访问控制 (RBAC) 、基于上下文的访问控制或这些的任意组合的策略。

Keycloak通过提供聚合策略的概念来利用策略的概念以及如何定义策略,您可以在其中构建 “策略策略” 并仍然控制评估的行为。 Keycloak Authorization Services中的策略实现遵循分而治之技术,而不是编写具有访问给定资源必须满足的所有条件的大型策略。 也就是说,您可以创建单个策略,然后以不同的权限重用它们,并通过组合单个策略来构建更复杂的策略。

策略提供者

策略提供者是特定策略类型的实现。 Keycloak提供内置策略,并由其相应的 策略提供程序,您可以创建自己的策略类型来支持您的特定需求。

Keycloak提供了一个SPI (服务提供者接口),您可以使用它来插入自己的策略提供者实现。

权限票

权限票证是由用户管理访问 (UMA) 规范定义的一种特殊类型的令牌,它提供了一种不透明的结构,其形式由授权服务器确定。 这个 结构表示客户端请求的资源和/或范围、访问上下文以及必须应用于授权数据请求的策略 (请求方令牌 [RPT])。

在UMA中,许可票对于支持人与人之间的共享以及人与组织之间的共享至关重要。 将权限票证用于授权工作流可以实现从简单到复杂的一系列方案,其中资源所有者和资源服务器可以根据管理对这些资源的访问的细粒度策略完全控制其资源。

在UMA工作流中,权限票证由授权服务器向资源服务器发出,资源服务器将权限票证返回给试图访问受保护资源的客户端。 客户端收到票证后,可以通过将票证发送回授权服务器来请求RPT (保存授权数据的最终令牌)。

有关权限票证的更多信息,请参见用户管理访问乌玛规格。

开始

在使用本教程之前,您需要完成Keycloak的安装并创建初始管理员用户,如入门指南教程。 对此有一个警告。 您必须在与Keycloak服务器相同的计算机上运行单独的WildFly实例。 这个单独的实例将运行您的Java Servlet应用程序。 因此,您将不得不在不同的端口下运行Keycloak,以便在同一台计算机上运行时没有端口冲突。 使用jboss.套接字.绑定.端口偏移命令行上的系统属性。 此属性的值是一个数字,该数字将添加到Keycloak Server打开的每个端口的基本值中。

要启动Keycloak服务器:

Linux/Unix
$。../bin/standalone.sh -Djboss.socket.binding.port-offset = 100
窗户
>。.. \ bin \ standalone.bat -Djboss.套接字.绑定.端口偏移 = 100

有关如何安装和配置WildFly的更多详细信息,请按照保护应用程序和服务指南教程。

安装并启动两台服务器后,您应该能够在以下位置访问Keycloak管理控制台http:// localhost:8180/auth/admin/还有WildFly实例 http:// localhost:8080

保护Servlet应用程序

本入门指南的目的是让您尽快启动并运行,以便您可以尝试和测试Keycloak提供的各种授权功能。 此快速浏览在很大程度上依赖于默认的数据库和服务器配置,并且不涵盖复杂的部署选项。 有关功能或配置选项的更多信息,请参阅本文档中的相应部分。

本指南解释了有关Keycloak授权服务的关键概念:

  • 为客户端应用程序启用细粒度授权

  • 将客户端应用程序配置为具有受保护资源的资源服务器

  • 定义权限和授权策略来管理对受保护资源的访问

  • 在您的应用程序中启用策略实施。

创建境界和用户

本教程的第一步是创建一个领域和该领域中的用户。 然后,在领域内,我们将创建一个单一的客户端应用程序,然后它成为一个资源服务器您需要为此启用授权服务。

要创建境界和用户,请完成以下步骤:

  1. 创建一个有名字的境界你好-世界-作者。 创建后,将显示类似于以下的页面:

    领域你好-世界-作者

    领域你好-世界-作者

  2. 为您新创建的领域创建用户。 点击用户。 用户列表页打开。

  3. 在空用户列表的右侧,单击添加用户

  4. 要创建新用户,请完成用户名,电子邮件,名字,以及姓氏字段。 单击用户启用切换到,然后单击保存

    添加用户

    添加用户

  5. 通过单击为用户设置密码凭据tab。

    设置用户密码

    设置用户密码

  6. 完成新密码密码确认带有密码的字段,然后单击临时切换到

  7. 点击设置密码来设置用户的密码。

启用授权服务

您可以在配置为使用OpenID Connect协议的现有客户端应用程序中启用授权服务。 您还可以创建一个新的客户端。

要创建新客户端,请完成以下步骤:

  1. 点击客户要开始创建新的客户端应用程序并填写客户端ID,客户端协议,以及根URL字段。

    创建客户端应用程序

    创建客户端应用程序

  2. 点击保存。 显示客户端详细信息页面。

  3. 在客户端详细信息页面上,选择机密访问类型字段,更改已启用授权切换到,然后单击保存。 一个新的授权为客户端显示选项卡。

    客户详细信息

    客户详细信息

  4. 单击授权tab和类似以下的授权设置页面显示:

    授权设置

    授权设置

当您为客户端应用程序启用授权服务时,Keycloak会自动创建多个默认设置用于您的客户端授权配置。

有关授权配置的更多信息,请参见启用授权服务

构建、部署和测试您的应用程序

现在应用程序-authz-香草资源服务器 (或客户端) 已正确配置并启用了授权服务,可以将其部署到服务器。

您要部署的应用程序的项目和代码可在Keycloak快速启动存储库。 您将需要以下内容 安装在您的计算机上,并在您的路径中可用,然后才能继续:

  • Java JDK 8

  • Apache Maven 3.1.1或更高版本

  • Git

您可以通过在以下位置克隆存储库来获取代码https://github.com/keycloak/ Keycloak-快速入门。 快速入门旨在与最新的Keycloak版本一起使用。

按照以下步骤下载代码。

克隆项目
$ git克隆https://github.com/keycloak/ keycloak-快速入门

我们将要构建和部署的应用程序位于

$ cdKeycloak-快速入门/应用-authz-jee-香草

获取适配器配置

在构建和部署应用程序之前,您必须首先获取适配器配置。

要从Keycloak管理控制台获取适配器配置,请完成以下步骤。

  1. 点击客户。 在客户端列表中,单击应用程序-authz-香草客户端应用程序。 将打开 “客户端详细信息” 页面。

    客户详细信息

    客户详细信息

  2. 单击安装tab。 从 “格式选项” 下拉列表中,选择KeycloakOIDC JSON。 适配器配置以JSON格式显示。 点击下载

    适配器配置

    适配器配置

  3. 移动文件Keycloak。json应用程序-authz-jee-香草/配置目录。

  4. (可选) 默认情况下,策略执行者以403当用户缺乏访问资源服务器上受保护资源的权限时的状态代码。 但是,您也可以为未经授权的用户指定重定向URL。 要指定重定向URL,请编辑Keycloak。json您在步骤3中更新的文件,并替换政策执行者配置如下:

    政策执行者: {
        拒绝重定向到:/app-authz-vanilla/error.jsp
    }

    此更改指定策略执行者将用户重定向到/app-authz-vanilla/error.jsp如果用户没有必要的权限来访问受保护的资源,而不是无益的页面403未经授权消息。

构建和部署应用程序

要构建和部署应用程序,请执行以下命令:

$ cdKeycloak-快速入门/应用-authz-jee-香草
$ mvn清洁包wildfly: 部署

测试应用程序

如果您的应用程序已成功部署,您可以在http:// localhost:8080/app-authz-vanilla。 Keycloak登录页面打开。

登录页面

登录页面

登录为爱丽丝使用您为该用户指定的密码。 身份验证后,显示以下页面:

你好世界Authz主页

你好世界Authz主页

默认设置当您为客户端应用程序启用授权服务时,由Keycloak定义提供了一个简单的 始终授予对受此策略保护的资源的访问权限的策略。

您可以从更改默认权限和策略开始,并测试应用程序的响应方式,甚至使用不同的 策略类型由Keycloak提供。

现在你可以做很多事情来测试这个应用程序。 例如,您可以通过单击客户端的 “授权” 选项卡来更改默认策略,然后政策选项卡,然后单击默认策略在列表中允许您如下更改:

// 默认值为 $ evalue.grant(),
// 让我们看看将其更改为 $ evaluation.de ny() 时会发生什么
$ 评价。拒绝 ();

现在,注销演示应用程序并再次登录。 您不能再访问该应用程序。

访问被拒绝页面

让我们现在解决这个问题,而不是改变默认策略代码我们要改变逻辑阴性使用策略代码文本区域下方的下拉列表。 当我们否定该策略的结果时,它会重新启用对应用程序的访问,默认情况下,该策略会拒绝所有访问请求。 同样,在测试此更改之前,请确保注销并再次登录。

下一步

您可以做其他事情,例如:

  • 创建作用域,为其定义策略和权限,并在应用程序端对其进行测试。 用户可以执行操作 (或您创建的范围所代表的任何其他操作) 吗?

  • 创建不同类型的策略,例如基于JavaScript的,并将这些策略与默认权限

  • 将多个策略应用于默认权限测试行为。 例如,组合多个策略并更改决策策略相应地。

  • 有关如何查看和测试应用程序中的权限的更多信息,请参见获取授权上下文

授权快速启动

除了应用程序-authz-jee-香草在上一节中用作示例应用程序的quickstart, Keycloak快速启动存储库包含使用授权服务的其他应用程序 在本文档中描述。

设计了授权快速入门,以便在不同的场景中显示授权服务,并且 使用不同的技术和集成。 它并不是指所有可能的用例的综合集合,其中涉及 授权,但它们应该为有兴趣了解授权服务的用户提供一个起点 可以在自己的应用程序中使用。

每个快速入门都有一个自述文件文件中包含有关如何构建,部署和测试示例应用程序的说明。 以下内容 表提供了可用授权快速入门的简要说明:

表1。 授权快速启动
名称 描述

应用程序-authz-jee-servlet

演示如何对Java EE应用程序启用细粒度授权,以保护特定资源并基于从Keycloak服务器获得的权限构建动态菜单。

应用程序-authz-jee-香草

演示如何对Java EE应用程序启用细粒度授权,并使用默认授权设置来保护应用程序中的所有资源。

应用程序-authz-休息-springboot

演示如何使用Keycloak授权服务保护SpringBoot REST服务。

应用程序-authz-springboot

演示如何编写一个SpringBoot Web应用程序,其中身份验证和授权方面都由Keycloak管理。

应用程序-authz-uma-photoz

一个基于HTML5 AngularJS JAX-RS的简单应用程序,演示如何启用用户管理的对应用程序的访问,并让用户管理其资源的权限。

管理资源服务器

根据OAuth2规范,资源服务器是托管受保护资源并能够接受和响应受保护资源请求的服务器。

在Keycloak中,资源服务器提供了一个丰富的平台,用于对其受保护的资源实现细粒度的授权,其中可以根据不同的访问控制机制做出授权决策。

任何客户端应用程序都可以配置为支持细粒度的权限。 在这样做的过程中,您在概念上将客户端应用程序转换为资源服务器。

创建客户端应用程序

启用Keycloak授权服务的第一步是创建要转换为资源服务器的客户端应用程序。

要创建客户端应用程序,请完成以下步骤:

  1. 点击客户

    客户

    客户

  2. 在此页面上,单击创建

    创建客户端

    创建客户端

  3. 键入客户端ID客户的。 例如,我的资源服务器

  4. 键入根URL为你的申请。 例如:

    http:// $ {主机 }:${ 端口}/my-resource-server
  5. 点击保存。 创建客户端,并打开客户端设置页面。 显示与以下类似的页面:

    客户端设置

    客户端设置

启用授权服务

要将您的OIDC客户端应用程序转换为资源服务器并启用细粒度授权,请选择访问类型 机密并单击已启用授权切换到然后点击保存

启用授权服务

启用授权服务

显示此客户端的新授权选项卡。 单击授权tab并显示类似以下的页面:

资源服务器设置

资源服务器设置

“授权” 选项卡包含其他子选项卡,这些子选项卡涵盖了实际保护应用程序资源必须遵循的不同步骤。 本文档中的特定主题分别涵盖了每个选项卡。 但是这里有一个关于每一个的快速描述:

  • 设置

    资源服务器的常规设置。 有关此页面的更多详细信息,请参见资源服务器设置节。

  • 资源

    在此页面中,您可以管理应用程序的资源

  • 授权范围

    在此页面中,您可以管理范围

  • 政策

    在此页面中,您可以管理授权策略并定义授予权限必须满足的条件。

  • 权限

    在此页面中,您可以管理权限通过将受保护的资源和范围与您创建的策略链接起来。

  • 评估

    从这一页,你可以模拟授权请求并查看您定义的权限和授权策略的评估结果。

  • 导出设置

    从这一页,你可以导出JSON文件的授权设置。

资源服务器设置

在资源服务器设置页面,您可以配置策略执行模式、允许远程资源管理和导出授权配置设置。

  • 政策执行模式

    指定在处理发送到服务器的授权请求时如何强制执行策略。

    • 强制执行

      (默认模式) 即使没有与给定资源关联的策略,也会默认拒绝请求。

    • 允许

      即使没有与给定资源关联的策略,也允许请求。

    • 禁用

      禁用所有策略的评估,并允许访问所有资源。

  • 决策策略

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

  • 远程资源管理

    指定资源服务器是否可以远程管理资源。 如果为false,则只能从管理控制台管理资源。

默认配置

创建资源服务器时,Keycloak为新创建的资源服务器创建默认配置。

默认配置包括:

  • 代表应用程序中所有资源的默认受保护资源。

  • 一种策略,该策略始终授予对受此策略保护的资源的访问权限。

  • 根据默认策略管理对所有资源的访问的权限。

默认的受保护资源称为默认资源如果您导航到资源tab。

默认资源

默认资源

此资源定义了一个类型,即urn: 我的资源服务器: 资源: 默认值和一个URI /*。 在这里,URI字段定义了一个 通配符模式,向Keycloak指示此资源表示应用程序中的所有路径。 换句话说, 启用时政策执行对于您的应用程序,与资源关联的所有权限 将在授予访问权限之前进行检查。

类型前面提到的定义了一个值,可以用来创建类型化资源权限必须适用 到默认资源或使用相同类型创建的任何其他资源。

默认策略称为仅来自领域政策如果您导航到政策tab。

默认策略

默认策略

这项政策是一项基于JavaScript的策略定义一个条件,该条件始终授予对受此策略保护的资源的访问权限。 如果单击此策略,则可以看到它定义了如下规则:

// 默认情况下,授予与此策略关联的任何权限
$ 评价。格兰特 ();

最后,默认权限称为默认权限如果您导航到权限tab。

默认权限

默认权限

此权限是基于资源的权限,定义一组应用于具有给定类型的所有资源的一个或多个策略。

更改默认配置

您可以通过删除默认资源、策略或权限定义并创建自己的来更改默认配置。

默认资源是使用URI映射到应用程序中的任何资源或路径,使用/* 图案。 在创建自己的资源、权限和策略之前,请 确保默认配置不会与您自己的设置冲突。

默认配置定义了映射到应用程序中所有路径的资源。 如果您要为自己的资源编写权限,请确保删除默认资源或者改变它的Uuri字段到应用程序中更特定的路径。 否则,与默认资源 (默认情况下始终授予访问权限) 关联的策略将允许Keycloak授予对任何受保护资源的访问权限。

导出和导入授权配置

可以导出和下载资源服务器 (或客户端) 的配置设置。 您还可以为资源服务器导入现有的配置文件。 当您要为资源服务器创建初始配置或更新现有配置时,导入和导出配置文件很有帮助。 配置文件包含以下内容的定义:

  • 受保护的资源和范围

  • 政策

  • 权限

导出配置文件

要导出配置文件,请完成以下步骤:

  1. 导航到资源服务器设置页。

  2. 单击导出设置tab。

  3. 在此页面上,单击导出

    导出设置

    导出设置

配置文件以JSON格式导出,并显示在文本区域中,您可以从中复制和粘贴。 您也可以单击下载下载配置文件并保存。

导入配置文件

要导入配置文件,请完成以下步骤:

  1. 导航到资源服务器设置页。

    导入设置

    导入设置

要导入资源服务器的配置文件,请单击选择文件选择包含要导入的配置的文件。

管理资源和范围

资源管理是简单明了的。 创建资源服务器后,可以开始创建要保护的资源和范围。 资源和范围可以通过导航到资源范围选项卡。

查看资源

资源在页面中,您会看到与资源服务器关联的资源列表。

资源

资源

资源列表提供有关受保护资源的信息,例如:

  • 类型

  • Uuri

  • 所有者

  • 关联范围 (如果有)

  • 关联权限

在此列表中,您还可以通过单击直接创建权限创建权限对于要为其创建权限的资源。

在为资源创建权限之前,请确保您已经定义了要与权限关联的策略。

创建资源

创建资源是直接和通用的。 您主要关注的是您创建的资源的粒度。 换句话说,资源可以 创建以表示一组一个或多个资源,并且定义它们的方式对于管理权限至关重要。

要创建新资源,请单击创建在资源列表的右上角。

添加资源

添加资源

在Keycloak中,资源定义了一小部分信息,这些信息对于不同类型的资源是共有的,例如:

  • 名称

    描述此资源的人类可读且独特的字符串。

  • 类型

    唯一标识一组一个或多个资源的类型的字符串。 类型是字符串用于对不同的资源实例进行分组。 例如,自动创建的默认资源的默认类型为urn: 资源-服务器-名称: 资源: 默认值

  • Uuri

    提供资源位置/地址的uri。 对于HTTP资源,uri 通常是用于服务这些资源的相对路径。

  • 范围

    要与资源关联的一个或多个作用域。

资源属性

资源可能具有与之相关联的属性。 这些属性可用于提供有关 资源,并在评估与资源关联的权限时向策略提供其他信息。

每个属性都是一个键和值对,其中值可以是一个或多个字符串的集合。 通过用逗号分隔每个值,可以为一个属性定义多个值。

类型化资源

资源的类型字段可用于将不同的资源分组在一起,因此可以使用一组通用权限对它们进行保护。

资源所有者

资源也有一个所有者。 默认情况下,资源归资源服务器所有。

但是,资源也可以与用户关联,因此您可以根据资源所有者创建权限。 例如,仅允许资源所有者删除或更新给定资源。

远程管理资源

资源管理也通过保护API允许资源服务器远程管理其资源。

当使用保护API时,资源服务器可以被实现来管理其用户拥有的资源。 在这种情况下,你可以 指定用户标识符以将资源配置为属于特定用户。

Keycloak为资源服务器提供对其资源的完全控制。 将来,我们应该能够 允许用户控制自己的资源以及批准授权请求和管理权限,尤其是在使用UMA协议时。

管理策略

如前所述,策略定义了在授予对象访问权限之前必须满足的条件。

您可以通过单击政策编辑资源服务器时的选项卡。

政策

政策

在此选项卡上,您可以查看以前创建的策略列表以及创建和编辑策略。

要创建新策略,请在策略列表的右上角,从创建策略下拉列表。 本节介绍了每种策略类型的详细信息。

基于用户的策略

您可以使用这种类型的策略为您的权限定义条件,其中允许一个或多个用户的集合访问对象。

要创建新的基于用户的策略,请选择用户在策略列表右上角的下拉列表中。

添加基于用户的策略

添加基于用户的策略

配置

  • 名称

    标识策略的人类可读且唯一的字符串。 最佳做法是使用与您的业务和安全要求密切相关的名称,因此您 可以更容易地识别他们。

  • 描述

    包含有关此策略的详细信息的字符串。

  • 用户

    指定此策略授予哪些用户访问权限。

  • 逻辑

    逻辑在评估其他条件后适用本政策。

基于角色的策略

您可以使用这种类型的策略为您的权限定义条件,其中允许一组一个或多个角色访问对象。

默认情况下,未按要求指定添加到此策略中的角色,并且如果请求访问的用户已被授予这些角色中的任何一个,则该策略将授予访问权限。 但是,您可以将特定角色指定为必需如果你想强制执行一个特定的角色。 您还可以组合必需角色和非必需角色,无论它们是领域角色还是客户端角色。

当您需要更受限制的基于角色的访问控制 (RBAC) 时,角色策略可能会很有用,因为必须强制执行特定角色才能授予对对象的访问权限。 例如,您可以强制要求用户必须同意允许客户端应用程序 (代表用户行事) 访问用户的资源。 您可以使用Keycloak客户端作用域映射来启用同意页面,甚至强制客户端在从Keycloak服务器获取访问令牌时显式提供作用域。

要创建新的基于角色的策略,请选择角色在策略列表右上角的下拉列表中。

添加基于角色的策略

添加基于角色的策略

配置

  • 名称

    描述策略的人类可读且唯一的字符串。 最佳做法是使用与您的业务和安全要求密切相关的名称,因此您 可以更容易地识别他们。

  • 描述

    包含有关此策略的详细信息的字符串。

  • 领域角色

    指定哪个境界此策略允许角色。

  • 客户角色

    指定哪个客户此策略允许角色。 要启用此字段,必须首先选择一个客户

  • 逻辑

    逻辑在评估其他条件后适用本政策。

根据需要定义角色

创建基于角色的策略时,可以将特定角色指定为必需。 当您这样做时,策略将授予访问权限 仅当请求访问的用户被授予全部必需角色。 领域和客户端角色都可以这样配置。

所需角色示例

所需角色示例

要根据需要指定角色,请选择必需您要根据需要配置的角色的复选框。

当您的策略定义多个角色时,所需角色可能会很有用,但只有这些角色的子集是强制性的。 在这种情况下,您可以结合领域和客户端角色来启用 为您的应用程序提供更细粒度的基于角色的访问控制 (RBAC) 模型。 例如,您可以具有特定于客户端的策略,并需要与该客户端关联的特定客户端角色。 或者,您可以强制执行仅在存在特定领域角色的情况下才授予访问权限。 您还可以在同一策略中组合这两种方法。

基于JavaScript的策略

如果您的策略实现正在使用以下示例中的基于属性的访问控制 (ABAC),则请确保 用户无法编辑受保护的属性,并且相应的属性是只读的。 请参阅中的详细信息威胁模型缓解章节

您可以使用这种类型的策略使用JavaScript为您的权限定义条件。 它是基于规则的策略类型之一 由Keycloak支持,并提供了根据评估API

要创建新的基于JavaScript的策略,请选择JavaScript在策略列表右上角的下拉列表中。

默认情况下,JavaScript策略无法上传到服务器。 您应该更喜欢直接将JS策略部署到 中所述的服务器JavaScript提供商。 如果您仍然想使用 Keycloak管理控制台要管理您的JS策略,您应该启用上传脚本特征。
添加JavaScript策略

添加JavaScript策略

配置

  • 名称

    描述策略的人类可读且唯一的字符串。 最佳做法是使用与您的业务和安全要求密切相关的名称,因此您 可以更容易地识别他们。

  • 描述

    包含有关此策略的详细信息的字符串。

  • 代码

    提供此策略条件的JavaScript代码。

  • 逻辑

    逻辑在评估其他条件后适用本政策。

从已部署的JAR文件创建JS策略

Keycloak允许您部署JAR文件,以便将脚本部署到服务器。 请看看JavaScript提供商 有关更多详细信息。

部署脚本后,您应该能够从可用策略提供程序列表中选择部署的脚本。

示例

从评估上下文检查属性

这是一个基于JavaScript的策略的简单示例,该策略使用基于属性的访问控制 (ABAC) 基于属性定义条件 从执行上下文获得:

var上下文 =$ 评价。getContext();
varcontextAttributes = context.getAttributes();

如果(contextAttributes。包含值 ('kc.client.net工作。ip_address','127.0.0.1')) {
    $ 评价。格兰特 ();
}
从当前标识检查属性

这是一个基于JavaScript的策略的简单示例,该策略使用基于属性的访问控制 (ABAC) 基于属性定义条件 获得与当前标识关联的:

var上下文 =$ 评价。getContext();
var身份 = 上下文。getIdentity();
var属性 = identity.getAttributes();
var电子邮件 = 属性。获取值 ('电子邮件')。asString (0);

如果(电子邮件。结束 ('@ keycloak.org')) {
    $ 评价。格兰特 ();
}

这些属性与授权请求中使用的令牌中定义的任何声明相映射。

检查授予当前身份的角色

您还可以在策略中使用基于角色的访问控制 (RBAC)。 在下面的示例中,我们检查用户是否被授予keycloak_user 境界角色:

var上下文 =$ 评价。getContext();
var身份 = 上下文。getIdentity();

如果(身份。hasRealmRole ('keycloak_user')) {
    $ 评价。格兰特 ();
}

或者您可以检查用户是否被授予我的客户角色 客户角色,在哪里我的客户是客户端应用程序的客户端id:

var上下文 =$ 评价。getContext();
var身份 = 上下文。getIdentity();

如果(身份。hasClientRole ('我的客户','我的客户角色')) {
    $ 评价。格兰特 ();
}
检查授予用户的角色

要检查授予用户的领域角色:

var领域 =$ 评价。getRealm();

如果(领域。isUserInRealmRole ('玛尔塔','角色-a')) {
    $ 评价。格兰特 ();
}

或授予用户的客户端角色:

var领域 =$ 评价。getRealm();

如果(领域。isUserInClientRole ('玛尔塔','我的客户','一些客户角色')) {
    $ 评价。格兰特 ();
}
检查授予组的角色

要检查授予组的领域角色:

var领域 =$ 评价。getRealm();

如果(领域。是groupinrole ('/A组/D组','角色-a')) {
    $ 评价。格兰特 ();
}
将任意声明推送到资源服务器

将任意声明推送到资源服务器,以便提供有关权限应如何的其他信息 强制执行:

var权限 =$ 评价。getPermission();

// 决定是否应该授予权限

如果(授予) {
    权限。添加声明 ('索赔-a','索赔-a');
    权限。添加声明 ('索赔-a','claim-a1');
    权限。添加声明 ('索赔-b','索赔-b');
}
检查组成员资格
var领域 =$ 评价。getRealm();

如果(领域。isUserInGroup ('玛尔塔','/A组/B组')) {
    $ 评价。格兰特 ();
}
混合不同的访问控制机制

您还可以使用几种访问控制机制的组合。 下面的示例显示了角色 (RBAC) 和 声明/属性 (ABAC) 检查可以在同一策略中使用。 在这种情况下,我们检查用户是否被授予管理员角色 或者有一封来自keycloak.org域:

var上下文 =$ 评价。getContext();
var身份 = 上下文。getIdentity();
var属性 = identity.getAttributes();
var电子邮件 = 属性。获取值 ('电子邮件')。asString (0);

如果(身份。hasRealmRole ('管理员') | | 电子邮件。结束 ('@ keycloak.org')) {
    $ 评价。格兰特 ();
}
在编写自己的规则时,请记住$ 评价对象是一个实现对象组织。Keycloak。授权。政策。评估。 有关可以从此界面访问内容的更多信息,请参见评估API

基于时间的策略

您可以使用这种类型的策略为您的权限定义时间条件。

要创建新的基于时间的策略,请选择时间在策略列表右上角的下拉列表中。

添加时间策略

添加时间策略

配置

  • 名称

    描述策略的人类可读且唯一的字符串。 最佳做法是使用与您的业务和安全要求密切相关的名称,因此您 可以更容易地识别他们。

  • 描述

    包含有关此策略的详细信息的字符串。

  • 以前没有

    定义访问必须之前的时间不是被授予。 仅当当前日期/时间晚于或等于此值时,才授予权限。

  • 不在或之后

    定义访问必须经过的时间不是被授予。 仅当当前日期/时间早于或等于此值时,才授予权限。

  • 月中的一天

    定义必须授予访问权限的月份。 您还可以指定日期范围。 在这种情况下,仅当当月的当前日期介于或等于指定的两个值时才授予权限。

  • 定义必须授予访问权限的月份。 您还可以指定月份范围。 在这种情况下,仅当当前月份在指定的两个值之间或等于两个值时才授予权限。

  • 定义必须授予访问权限的年份。 您还可以指定年份的范围。 在这种情况下,仅当当前年份介于或等于指定的两个值之间时才授予权限。

  • 小时

    定义必须授予访问权限的小时。 您还可以指定小时数的范围。 在这种情况下,仅当当前小时在指定的两个值之间或等于时才授予权限。

  • 分钟

    定义必须授予访问权限的分钟。 您还可以指定分钟的范围。 在这种情况下,仅当当前分钟在指定的两个值之间或等于时才授予权限。

  • 逻辑

    逻辑在评估其他条件后适用本政策。

仅在满足所有条件时才授予访问权限。 Keycloak将执行根据每种情况的结果。

聚合策略

如前所述,Keycloak允许您构建策略策略,该概念称为策略聚合。 您可以使用策略聚合来重用现有策略来构建更复杂的策略,并使您的权限与在处理授权请求期间评估的策略更加分离。

要创建新的聚合策略,请选择聚合在位于策略列表右上角的下拉列表中。

添加聚合策略

添加聚合策略

让我们假设你有一个名为保密资源只能由来自keycloak.org域和来自一定范围的ip地址。 您可以在两个条件下创建单个策略。 但是,您希望重用此策略的域部分,以应用于与原始网络无关的操作权限。

您可以为域和网络条件创建单独的策略,并根据这两个策略的组合创建第三个策略。 使用聚合策略,您可以自由组合其他策略,然后将新的聚合策略应用于所需的任何权限。

创建聚合策略时,请注意,您没有在策略之间引入循环引用或依赖关系。 如果检测到循环依赖关系,则无法创建或更新策略。

配置

  • 名称

    描述策略的人类可读且唯一的字符串。 我们强烈建议您使用与您的业务和安全需求密切相关的名称,因此您 可以更容易地识别它们,也知道它们的意思。

  • 描述

    包含有关此策略的更多详细信息的字符串。

  • 应用策略

    定义一组一个或多个策略,以与聚合策略相关联。 要关联策略,您可以选择现有策略 或通过选择要创建的策略的类型来创建新策略。

  • 决策策略

    此权限的决策策略。

  • 逻辑

    逻辑在评估其他条件后适用本政策。

聚合策略的决策策略

在创建聚合策略时,您还可以根据每个策略的结果定义将用于确定最终决策的决策策略。

  • 一致

    如果没有提供默认策略。 在这种情况下,全部政策必须评估一个积极的决定,最终决定也是积极的。

  • 肯定

    在这种情况下,至少有一个政策必须评估一个积极的决定,以便最终决定也是积极的。

  • 共识

    在这种情况下,肯定决策的数量必须大于否定决策的数量。 如果正面和负面决定的数量相同,则最终的决定将是负面的。

基于客户端的策略

您可以使用这种类型的策略为您的权限定义条件,其中允许一个或多个客户端的集合访问对象。

要创建新的基于客户端的策略,请选择客户在策略列表右上角的下拉列表中。

添加基于客户端的策略

添加基于客户端的策略

配置

  • 名称

    标识策略的人类可读且唯一的字符串。 最佳做法是使用与您的业务和安全要求密切相关的名称,因此您 可以更容易地识别他们。

  • 描述

    包含有关此策略的详细信息的字符串。

  • 客户

    指定此策略授予哪些客户端访问权限。

  • 逻辑

    逻辑在评估其他条件后适用本政策。

基于组的策略

您可以使用这种类型的策略为您的权限定义条件,其中允许一个或多个组 (及其层次结构) 的集合访问对象。

要创建新的基于组的策略,请选择在策略列表右上角的下拉列表中。

添加基于组的策略

添加基于组的策略

配置

  • 名称

    描述策略的人类可读且唯一的字符串。 最佳做法是使用与您的业务和安全要求密切相关的名称,因此您 可以更容易地识别他们。

  • 描述

    包含有关此策略的详细信息的字符串。

  • 团体索赔

    指定持有组名称和/或路径的令牌中声明的名称。 通常,授权请求是基于ID令牌或访问令牌来处理的 以前发布给代表某个用户行事的客户。 如果已定义,则令牌必须包含声明,该策略将从其中获取组 用户是的成员。 如果未定义,则从您的领域配置中获取用户组。

  • 允许您在评估权限时选择此策略应强制执行的组。 添加组后,您可以将访问权限扩展到该组的子组 通过标记复选框扩展到儿童。 如果保持未标记,则访问限制仅适用于所选组。

  • 逻辑

    逻辑在评估其他条件后适用本政策。

扩大对儿童群体的访问

默认情况下,当您将组添加到此策略时,访问限制将仅适用于所选组的成员。

在某些情况下,可能有必要不仅允许访问组本身,而且允许访问层次结构中的任何子组。 对于任何群体 已添加您可以标记复选框扩展到儿童为了扩大对儿童群体的访问。

扩大对儿童群体的访问

扩大对儿童群体的访问

在上面的示例中,策略正在为以下用户的任何用户成员授予访问权限或者它的任何孩子。

正负逻辑

策略可以配置正反逻辑。 简而言之,您可以使用此选项来定义策略结果应保持不变还是否定。

例如,假设您要创建一个策略,其中只有用户不是授予特定角色的权限。 在这种情况下, 您可以使用该角色创建基于角色的策略,并设置其逻辑字段到阴性。 如果你坚持阳性,其中 是默认行为,策略结果将保持不变。

策略评估API

在使用JavaScript编写基于规则的策略时,Keycloak提供了一个评估API,该API提供了有用的信息来帮助确定是否应该授予权限。

此API由几个接口组成,这些接口为您提供对信息的访问,例如

  • 正在评估的权限,代表所请求的资源和范围。

  • 与所请求资源关联的属性

  • 运行时环境和与执行上下文关联的任何其他属性

  • 有关用户的信息,例如组成员资格和角色

主界面是组织。Keycloak。授权。政策。评估,它定义了以下合同:

公众 接口 评价{

    /**
     * 返回要评估的 {@ link ResourcePermission}。
     *
     * @ 返回要评估的权限
     */
    ResourcePermission getPermission();

    /**
     * 返回 {@ link EvaluationContext}。 它提供了对整个评估运行时上下文的访问。
     *
     * @ 返回评估上下文
     */
    EvaluationContext getContext();

    /**
     * 返回一个策略可以用来查询信息的 {@ link Realm}。
     *
     * @ 返回一个 {@ link领域} 实例
     */
    境界格特雷姆 ();

    /**
     * 将请求的权限授予呼叫者。
     */
    虚空格兰特 ();

    /**
     * 拒绝请求的权限。
     */
    虚空拒绝 ();
}

在处理授权请求时,Keycloak会创建一个评价评估任何策略之前的实例。 然后将此实例传递给每个策略,以确定访问是否为格兰特或者否认

策略通过调用格兰特 ()或者拒绝 ()方法评价实例。 默认情况下,评价实例被拒绝,这意味着您的策略必须显式地调用格兰特 ()方法向策略评估引擎指示应授予权限。

有关评估API的更多信息,请参见Javadoc

评估背景

评估上下文在评估期间为策略提供了有用的信息。

公众 接口 评估上下文{

    /**
     * 返回 {@ link Identity},该 {@ link Identity} 表示必须向其授予或不授予权限的实体 (个人或非个人)。
     *
     * @ 返回必须授予或不授予权限的身份
     */
    身份获取实体 ();

    /**
     * 返回当前执行和运行时环境中的所有属性。
     *
     * @ 返回当前执行和运行时环境中的属性
     */
    属性getAttributes();
}

从这个接口,策略可以获得:

  • 经过身份验证的身份

  • 有关执行上下文和运行时环境的信息

身份是基于与授权请求一起发送的OAuth2访问令牌构建的,并且此构造可以访问所有声明 从原始令牌中提取。 例如,如果您使用的是协议映射器要在OAuth2访问令牌中包含自定义声明,您还可以访问此声明 从一个政策,并使用它来建立你的条件。

评估上下文还允许您访问与执行环境和运行时环境相关的属性。 目前,只有几个内置属性。

表2。 执行和运行时属性
名称 描述 类型

时间。日期 _ 时间

当前日期和时间

字符串。 格式MM/dd/yyyy hh:mm:ss

kc.client.net工作。ip_address

客户端的IPv4地址

字符串

kc.client.net工作。主持人

客户端的主机名

字符串

kc.客户端.id

客户端id

字符串

kc.客户端.用户代理

“用户代理” HTTP标头的值

字符串 []

kc.领域名称

领域的名称

字符串

管理权限

权限将受保护的对象与必须评估以决定是否应授予访问权限的策略相关联。

创建要保护的资源以及要用于保护这些资源的策略后, 您可以开始管理权限。 要管理权限,请单击权限编辑资源服务器时的选项卡。

权限

权限

可以创建权限来保护两种主要类型的对象:

  • 资源

  • 范围

要创建权限,请从权限列表右上角的下拉列表中选择要创建的权限类型。 以下各节将更详细地描述这两种类型的对象。

创建基于资源的权限

基于资源的权限定义了一组一个或多个资源,以使用一组一个或多个授权策略进行保护。

要创建新的基于资源的权限,请选择基于资源的在权限列表右上角的下拉列表中。

添加基于资源的权限

添加基于资源的权限

配置

  • 名称

    描述权限的人类可读且唯一的字符串。 最佳做法是使用与您的业务和安全要求密切相关的名称,因此您 可以更容易地识别他们。

  • 描述

    包含有关此权限的详细信息的字符串。

  • 应用于资源类型

    指定是否将权限应用于具有给定类型的所有资源。 选择此字段时,系统会提示您输入要保护的资源类型。

    • 资源类型

      定义要保护的资源类型。 定义后,将针对与该类型匹配的所有资源评估此权限。

  • 资源

    定义一组要保护的一个或多个资源。

  • 应用策略

    定义一组与权限关联的一个或多个策略。 要关联策略,您可以选择现有策略 或通过选择要创建的策略的类型来创建新策略。

  • 决策策略

    决策策略为了这个许可。

类型化资源权限

资源权限还可以用于定义策略,这些策略将应用于具有给定资源的所有资源类型。 当您拥有共享公共访问要求和约束的资源时,这种基于资源的权限形式可能会很有用。

通常,可以根据应用程序封装的数据或提供的功能对应用程序中的资源进行分类 (或键入)。 例如,金融应用程序可以管理不同的银行账户,其中每个账户属于特定客户。 尽管它们是不同的银行帐户,但它们具有共同的安全要求和约束,这些要求和约束是由银行组织全局定义的。 使用类型化资源权限,您可以定义通用策略以应用于所有银行帐户,例如:

  • 只有所有者可以管理他的帐户

  • 仅允许从所有者的国家和/或地区访问

  • 强制执行特定的身份验证方法

要创建类型化资源权限,请单击应用于资源类型创建新的基于资源的权限时。 与应用于资源类型设置为, 您可以指定要保护的类型以及要用于管理对指定类型的所有资源的访问的策略。

类型化资源权限示例

类型化资源权限示例

创建基于范围的权限

基于范围的权限定义了一组一个或多个范围,以使用一组一个或多个授权策略进行保护。 与基于资源的权限不同,您不仅可以使用此权限类型为资源创建权限,还可以为与其关联的范围创建权限,从而在定义管理资源的权限以及可以对资源执行的操作时提供更多的粒度。

要创建新的基于范围的权限,请选择基于范围的在权限列表右上角的下拉列表中。

添加基于作用域的权限

添加基于作用域的权限

配置

  • 名称

    描述权限的人类可读且唯一的字符串。 最佳做法是使用与您的业务和安全要求密切相关的名称,因此您 可以更容易地识别他们。

  • 描述

    包含有关此权限的详细信息的字符串。

  • 资源

    将范围限制为与所选资源关联的范围。 如果没有选择,则所有作用域都可用。

  • 范围

    定义一组要保护的一个或多个作用域。

  • 应用策略

    定义一组与权限关联的一个或多个策略。 要关联策略,您可以选择现有策略 或通过选择要创建的策略的类型来创建新策略。

  • 决策策略

    决策策略为了这个许可。

政策决策策略

将策略与权限关联时,还可以定义决策策略,以指定如何评估关联策略的结果以确定访问权限。

  • 一致

    如果没有提供默认策略。 在这种情况下,全部政策必须评估一个积极的决定,最终决定也是积极的。

  • 肯定

    在这种情况下,至少有一个政策必须评估一个积极的决定,最终决定也是积极的。

  • 共识

    在这种情况下,肯定决策的数量必须大于否定决策的数量。 如果正面和负面决定的数量相等,则最终的决定将是负面的。

评估和测试策略

在设计策略时,您可以模拟授权请求,以测试如何评估策略。

您可以通过单击评估编辑资源服务器时的选项卡。 在那里,您可以指定不同的输入来模拟真实的授权请求并测试策略的效果。

政策评估工具

提供身份信息

身份信息过滤器可用于指定请求权限的用户。

提供上下文信息

上下文信息过滤器可用于定义评估上下文的其他属性,以便策略可以获得这些相同的属性。

提供权限

权限过滤器可用于构建授权请求。 您可以为一组一个或多个资源和范围请求权限。 如果你愿意 要根据所有受保护的资源和范围模拟授权请求,请单击添加没有指定任何资源或者范围

指定所需值后,单击评估

授权服务

Keycloak授权服务建立在众所周知的标准之上,例如OAuth2和用户管理的访问规范。

OAuth2客户端 (如前端应用程序) 可以使用令牌端点从服务器获取访问令牌,并使用 这些相同的令牌来访问受资源服务器保护的资源 (例如后端服务)。 同样, Keycloak授权服务为OAuth2提供扩展,以允许根据处理情况发布访问令牌 与所请求的资源或范围相关联的所有策略。 这意味着资源服务器可以强制访问 根据服务器授予并由访问令牌持有的权限,对其受保护的资源。 在密钥斗篷授权服务中 具有权限的访问令牌称为请求方令牌或简称RPT。

除了发布RPTs之外,Keycloak授权服务还提供了一组RESTful端点,这些端点允许资源服务器管理其受保护的 资源、范围、权限和策略,帮助开发人员将这些功能扩展或集成到他们的应用程序中,以便支持细粒度的授权。

发现授权服务端点和元数据

Keycloak提供了一个发现文档,客户端可以从中获取所有必要的信息以与之交互 Keycloak授权服务,包括端点位置和功能。

发现文件可以从以下位置获得:

卷曲-X得到 \
  http:// ${host }:${ port}/auth/realms/${realm}/。知名/uma2-configuration

哪里$ {主机 }:${ 端口}是运行Keycloak的主机名 (或ip地址) 和端口,以及$ {领域}的名字是 披着钥匙的王国。

结果,您应该得到如下响应:

{

    // 这里预计会有一些索赔

    // 这些是发现文档中有关授权服务端点位置的主要声明
    “token_endpoint”: “http:// ${host }:${ port}/auth/realms/${realm}/protocol/openid-connect/token”,
    "token_introspection_endpoint": "http:// ${host }:${ port}/auth/realms/${realm}/protocol/openid-connect/token/introspect",
    "资源注册端点": "http:// $ {主机 }:${ 端口}/身份验证/领域/$ {领域}/身份验证/保护/资源集",
    “permission_endpoint”: “http:// $ {主机 }:${ 端口}/auth/realms/${realm}/authz/protection/permission”,
    “policy_endpoint”: “http:// ${host }:${ port}/auth/realms/${realm}/authz/protection/uma-policy”
}

这些端点中的每一个都公开了一组特定的功能:

  • 令牌 _ 端点

    支持的OAuth2-compliant令牌端点urn:ietf:params:oauth:grant-type:uma-ticket授权类型。 通过这个 endpoint客户端可以发送授权请求并获得具有Keycloak授予的所有权限的RPT。

  • 令牌 _ 反省 _ 端点

    客户端可用于查询服务器以确定RPT的活动状态的OAuth2-compliant令牌自省端点 并确定与令牌相关联的任何其他信息,例如Keycloak授予的权限。

  • 资源 _ 注册 _ 端点

    符合UMA的资源注册端点,资源服务器可以使用该端点来管理其受保护的资源和范围。 此端点提供 操作在Keycloak中创建、读取、更新和删除资源和范围。

  • 权限 _ 端点

    符合UMA的权限端点,资源服务器可以使用该端点来管理权限票证。 此端点提供 操作在Keycloak中创建、读取、更新和删除权限票证。

获取权限

要从Keycloak获取权限,您可以向令牌端点发送授权请求。 因此,Keycloak将 评估与所请求的资源和范围相关联的所有策略,并发布具有所有权限的RPT 由服务器授予。

允许客户端使用以下参数向令牌端点发送授权请求:

  • Grant _ 类型

    此参数为必需。 一定是urn:ietf:params:oauth:grant-type:uma-ticket

  • 此参数为可选。 作为UMA授权过程的一部分,客户端收到的最近的许可票证。

  • 声明令牌

    此参数为可选。 表示服务器在评估时应考虑的其他声明的字符串 请求的资源和范围的权限。 此参数允许客户端将声明推送到Keycloak。 有关所有支持的令牌格式的更多详细信息,请参见声明 _ 令牌 _ 格式参数。

  • 声明 _ 令牌 _ 格式

    此参数为可选。 字符串,指示在声明令牌参数。 Keycloak支持两个令牌 格式:urn:ietf:params:oauth: 令牌类型: jwthttps://openid.net/specs/ openid-connect-core-1_0.html # IDToken。 的urn:ietf:params:oauth: 令牌类型: jwt格式 表示声明令牌参数引用访问令牌。 的https://openid.net/specs/ openid-connect-core-1_0.html # IDToken表示 声明令牌参数引用OpenID Connect ID令牌。

  • rpt

    此参数为可选。 以前发布的RPT,也应评估其权限并将其添加到新的RPT中。 此参数 允许拥有RPT的客户端执行按需添加权限的增量授权。

  • 权限

    此参数为可选。 表示客户端正在寻求访问的一组一个或多个资源和范围的字符串。 这个参数可以多次定义 为了请求对多个资源和作用域的权限。 此参数是对urn:ietf:params:oauth:grant-type:uma-ticket授予类型,以便允许客户端在没有 许可票。 字符串的格式必须是:资源id # SCOPE_ID。 例如:资源A # 范围A,资源A # 范围A,范围B,范围C,资源A,# 范围A

  • 观众

    此参数为可选。 客户端寻求访问的资源服务器的客户端标识符。 此参数是强制性的 以防权限参数已定义。 它用作Keycloak的提示,以指示应在其中评估权限的上下文。

  • 响应 _ 包括 _ 资源 _ 名称

    此参数为可选。 一个布尔值,向服务器指示资源名称是否应包含在RPT的权限中。 如果为false,则仅资源 包括标识符。

  • 响应 _ 权限 _ 限制

    此参数为可选。 一个整数N,它定义了RPT可以拥有的权限数量的限制。 当与 rpt参数,RPT中只会保留最后N个请求的权限。

  • 提交 _ 请求

    此参数为可选。 一个布尔值,指示服务器是否应对权限票证引用的资源和范围创建权限请求。 此参数仅在与参数作为UMA授权过程的一部分。

  • 响应 _ 模式

    此参数为可选。 一个字符串值,指示服务器应如何响应授权请求。 此参数在以下情况下特别有用 您主要对整体决策或服务器授予的权限感兴趣,而不是标准的OAuth2响应。 可能的值是:

    • 决定

      指示来自服务器的响应应仅通过返回以下格式的JSON来表示总体决策:

      {
          'result':
      }

      如果授权请求未映射到任何权限,则403返回HTTP状态代码。

    • 权限

      指示来自服务器的响应应包含服务器通过返回以下格式的JSON授予的任何权限:

      [
          {
              'rsd':'My Resource'
              'scopes': ['ew','update']
          },
      
          ...
      ]

      如果授权请求未映射到任何权限,则403返回HTTP状态代码。

客户端寻求访问受资源服务器保护的两个资源时的授权请求示例。

卷曲-X柱 \
  http:// $ {主机 }:${ 端口}/身份验证/领域/$ {领域}/协议/openid-连接/令牌 \
  -H “授权: 承载 $ {访问令牌}” \
  -- 数据 “grant_type = urn:ietf:params:oauth:grant-type:uma-ticket” \
  -- 数据 “受众 = {资源服务器客户端id}” \
  -- 数据 “权限 = 资源A # 范围A” \
  -- 数据 “权限 = 资源B # 范围B”

当客户端寻求对资源服务器保护的任何资源和范围的访问时,授权请求的示例。

卷曲-X柱 \
  http:// $ {主机 }:${ 端口}/身份验证/领域/$ {领域}/协议/openid-连接/令牌 \
  -H “授权: 承载 $ {访问令牌}” \
  -- 数据 “grant_type = urn:ietf:params:oauth:grant-type:uma-ticket” \
  -- 数据 “受众 = {资源 _ 服务器 _ 客户端 _ 标识}”

客户端在收到来自的权限通知单后寻求访问UMA受保护资源时的授权请求示例 作为授权过程一部分的资源服务器:

卷曲-X柱 \
  http:// $ {主机 }:${ 端口}/身份验证/领域/$ {领域}/协议/openid-连接/令牌 \
  -H “授权: 承载 $ {访问令牌}” \
  -- 数据 “grant_type = urn:ietf:params:oauth:grant-type:uma-ticket” \
  -- data "ticket =${ permission_ticket}

如果Keycloak评估流程导致权限的发布,它将发布与其相关联的RPT 权限:

Keycloak用RPT响应客户端
HTTP/1.1 200 OK
内容类型: 应用程序/json
...
{
    "访问令牌": "${rpt}",
}

来自服务器的响应就像使用其他授权类型时来自令牌端点的任何其他响应一样。 RPT可以从 的访问令牌响应参数。 如果客户端未被授权,Keycloak会以403HTTP状态代码:

Keycloak拒绝授权请求
HTTP/1.1 403禁止
内容类型: 应用程序/json
...
{
    "错误": "访问拒绝",
    "错误描述": "请求拒绝"
}

客户端身份验证方法

客户端需要对令牌端点进行身份验证才能获得RPT。 当使用urn:ietf:params:oauth:grant-type:uma-ticket 授权类型,客户端可以使用以下任何一种身份验证方法:

  • 承载令牌

    客户端应将访问令牌作为HTTP授权标头中的承载凭证发送到令牌端点。

    示例: 使用访问令牌对令牌端点进行身份验证的授权请求
    卷曲-X柱 \
      http:// $ {主机 }:${ 端口}/身份验证/领域/$ {领域}/协议/openid-连接/令牌 \
      -H “授权: 承载 $ {访问令牌}” \
      -- 数据 “grant_type = urn:ietf:params:oauth:grant-type:uma-ticket”

    当客户端代表用户行事时,此方法特别有用。 在这种情况下,承载令牌是先前由Keycloak发布给代表某些客户端的访问令牌 用户 (或代表自己)。 将考虑访问令牌表示的访问上下文来评估权限。 例如,如果访问令牌是代表用户A向客户端A发出的,则权限将取决于 用户A有权访问的资源和范围。

  • 客户端凭据

    客户端可以使用Keycloak支持的任何客户端身份验证方法。 例如,client_id/client_secret或JWT。

    示例: 使用客户端id和客户端秘密对令牌端点进行身份验证的授权请求
    卷曲-X柱 \
      http:// $ {主机 }:${ 端口}/身份验证/领域/$ {领域}/协议/openid-连接/令牌 \
      -H "授权: 基本cGhvdGg6L7Jl13RmfWgtkk = = pOnNlY3JldA = =" \
      -- 数据 “grant_type = urn:ietf:params:oauth:grant-type:uma-ticket”

推动索赔

从服务器获得权限时,您可以推送任意声明,以便拥有这些 评估权限时,您的策略可用的声明。

如果您正在从服务器获取权限没有使用权限票证 (UMA flow),您可以发送 对令牌端点的授权请求如下:

卷曲-X柱 \
  http:// $ {主机 }:${ 端口}/身份验证/领域/$ {领域}/协议/openid-连接/令牌 \
  -- 数据 “grant_type = urn:ietf:params:oauth:grant-type:uma-ticket” \
  -- 数据 “claim_token = ewogICAib3JnYW5pemF0aW9uIjogWyJhY21lIl0KfQ = =” \
  -数据 “claim_token_format = urn:ietf:params:oauth: 令牌类型: jwt” \
  -- 数据 “客户端id = {资源服务器客户端id}” \
  -- 数据 “客户端 _ 秘密 = {资源 _ 服务器 _ 客户端 _ 秘密}” \
  -- 数据 “受众 = {资源 _ 服务器 _ 客户端 _ 标识}”

声明令牌参数期望一个BASE64编码的JSON,其格式类似于下面的示例:

{
    组织: [acme]
}

该格式期望一个或多个声明,其中每个声明的值必须是字符串数组。

使用UMA推动索赔

有关使用UMA和权限票时如何推送声明的更多详细信息,请查看权限API

用户管理访问

Keycloak授权服务基于用户管理的访问或简称UMA。 UMA是一个规范 通过以下方式增强OAuth2功能:

  • 隐私

    如今,随着越来越多的数据和设备可用并连接到云,用户隐私正成为一个巨大的问题。 与 UMA和Keycloak,资源服务器可以增强其能力,以改善其资源在以下方面的保护方式 根据用户定义的策略授予权限的用户隐私。

  • 当事人对当事人授权

    资源所有者 (例如: 常规最终用户) 可以管理对其资源的访问并授权其他方 (例如: 常规最终用户) 访问这些资源。 这与OAuth2不同,OAuth2同意代表用户使用UMA的客户端应用程序 允许资源所有者以完全异步的方式同意访问其他用户。

  • 资源共享

    允许资源所有者管理对其资源的权限,并决定谁可以访问特定资源以及如何访问。 然后,Keycloak可以充当共享管理服务,资源所有者可以从中管理其资源。

Keycloak是提供大多数UMA功能的UMA 2.0兼容授权服务器。

作为示例,考虑用户Alice (资源所有者) 使用互联网银行服务 (资源服务器) 来管理他的银行帐户 (资源)。 有一天,爱丽丝决定 向会计专业人士鲍勃 (请求方) 开立她的银行账户。 但是,Bob应该只能访问view (scope) Alice的帐户。

作为资源服务器,网上银行服务必须能够保护Alice的银行帐户。 为此,它依赖于Keycloak 资源注册端点在服务器中创建代表Alice银行帐户的资源。

此时,如果Bob尝试访问Alice的银行帐户,访问将被拒绝。 网上银行服务定义了几个默认 银行账户政策。 其中之一是,只有所有者 (在这种情况下为Alice) 才被允许访问她的银行帐户。

但是,有关Alice隐私的互联网银行服务也允许她更改银行帐户的特定政策。 其中一个 她可以更改的政策是定义允许哪些人查看她的银行帐户。 为此,网上银行服务依赖于Keycloak 为Alice提供一个空间,她可以在其中选择个人以及允许他们访问的操作 (或数据)。 任何时候,爱丽丝 可以撤销对Bob的访问权限或授予其他权限。

授权流程

在UMA中,当客户端尝试访问受UMA保护的资源服务器时,授权过程开始。

受UMA保护的资源服务器在令牌为RPT的请求中期望承载令牌。 当客户端请求时 资源服务器上没有权限票证的资源:

客户端请求受保护的资源而不发送RPT
卷曲-X得到 \
  http:// ${host }:${ port}/my-resource-server/resource/1bfdfe78-a4e1-4c2d-b142-fc92b75b986f

资源服务器将响应发送回具有权限的客户端和一个as_uri带有位置的参数 为了获得RPT,应该将票证发送到的Keycloak服务器。

资源服务器以权限通知单响应
HTTP/1.1 401未经授权
WWW-Authenticate: UMA领域 = "$ {领域}",
    as_uri = "https:// ${host }:${ port}/auth/realms/${realm}",
    ticket = "016f84e8-f9b9-11e0-bd6f-0021cc6004de"

权限票是Keycloak权限API发行的一种特殊类型的令牌。 它们表示被请求的权限 (例如: 资源和范围) 以及与请求相关的任何其他信息。 仅允许资源服务器创建这些令牌。

现在,客户端具有权限票证以及Keycloak服务器的位置,客户端可以使用发现文档 获取令牌端点的位置并发送授权请求。

客户端向令牌端点发送授权请求,以获取RPT
卷曲-X柱 \
  http:// $ {主机 }:${ 端口}/身份验证/领域/$ {领域}/协议/openid-连接/令牌 \
  -H “授权: 承载 $ {访问令牌}” \
  -- 数据 “grant_type = urn:ietf:params:oauth:grant-type:uma-ticket” \
  -- data "ticket =${ permission_ticket}

如果Keycloak评估流程导致权限的发布,它将发布与其相关联的RPT 权限:

Keycloak用RPT响应客户端
HTTP/1.1 200 OK
内容类型: 应用程序/json
...
{
    "访问令牌": "${rpt}",
}

来自服务器的响应就像使用其他授权类型时来自令牌端点的任何其他响应一样。 RPT可以从 的访问令牌响应参数。 如果客户端无权拥有权限,则Keycloak会以403HTTP状态代码:

Keycloak拒绝授权请求
HTTP/1.1 403禁止
内容类型: 应用程序/json
...
{
    "错误": "访问拒绝",
    "错误描述": "请求拒绝"
}

提交权限请求

作为授权过程的一部分,客户端需要首先从受UMA保护的资源服务器获取权限票证,以便 在Keycloak令牌端点处将其与RPT交换。

默认情况下,Keycloak以403HTTP状态代码和请求 _ 拒绝如果无法向客户端发出RPT,则会出错。

Keycloak拒绝授权请求
HTTP/1.1 403禁止
内容类型: 应用程序/json
...
{
    "错误": "访问拒绝",
    "错误描述": "请求拒绝"
}

这样的响应意味着Keycloak无法发出具有权限票证表示的权限的RPT。

在某些情况下,客户端应用程序可能希望启动异步授权流,并让资源的所有者 被请求决定是否应该授予访问权限。 为此,客户可以使用提交 _ 请求请求参数沿 对令牌端点的授权请求:

卷曲-X柱 \
  http:// $ {主机 }:${ 端口}/身份验证/领域/$ {领域}/协议/openid-连接/令牌 \
  -H “授权: 承载 $ {访问令牌}” \
  -- 数据 “grant_type = urn:ietf:params:oauth:grant-type:uma-ticket” \
  -- 数据 “票 = ${permission_ticket} \
  -- 数据 “submit_request = true”

当使用提交 _ 请求参数,Keycloak将为拒绝访问的每个资源保留一个权限请求。 创建后,资源所有者可以检查其帐户并管理其权限请求。

您可以将此功能视为请求访问应用程序中的按钮,用户可以在其中要求其他用户访问其资源。

管理对用户资源的访问

用户可以使用Keycloak用户帐户服务管理对其资源的访问。 启用 此功能,您必须首先为您的领域启用用户管理的访问。 为此, 在Keycloak管理控制台中打开 “领域设置” 页面,并启用用户管理的访问开关。

我的资源

在左侧菜单上,我的资源选项指向一个页面,用户可以:

  • 管理权限请求需要我的批准

    本节包含所有等待批准的许可请求的列表。 这些请求连接到请求访问的各方 (用户) 一种特定的资源。 允许用户批准或拒绝这些请求。

  • 管理我的资源

    本节包含用户拥有的所有资源的列表。 用户可以单击资源以获取更多详细信息 并与他人共享资源。

  • 管理与我共享的资源

    本节包含与用户共享的所有资源的列表。

  • 管理您的请求等待批准

    本节包含等待其他用户批准的用户发送的权限请求列表,或 资源所有者。

当用户选择通过单击 “我的资源” 列表中的任何资源来详细说明自己的资源时,他将被重定向到 页面如下:

资源详细信息

用户可以在此页面上:

  • 管理有权使用此资源的人

    本节包含有权访问此资源的人员列表。 允许用户通过单击撤销访问权限 在撤销按钮或通过删除特定的权限

  • 与他人共享资源

    通过键入另一个用户的用户名或电子邮件,用户能够共享资源并选择他想要授予访问权限的权限。

保护API

保护API提供了一组符合UMA的端点,提供:

  • 资源管理

    有了这个端点,资源服务器可以远程管理他们的资源,并启用政策执行者向服务器查询需要保护的资源。

  • 权限管理

    在UMA协议中,资源服务器访问此端点以创建权限票证。 Keycloak还提供 用于管理权限状态和查询权限的端点。

  • 策略API

    Keycloak利用UMA保护API允许资源服务器管理其用户的权限。 此外 对于资源和权限API,Keycloak提供了一个策略API,可以从该策略API按资源将权限设置为资源 代表其用户的服务器。

这个API的一个重要要求是允许资源服务器使用称为保护API令牌 (PAT) 的特殊OAuth2访问令牌访问其端点。 在UMA中,PAT是具有范围的令牌Uma_ 保护

拍拍是什么以及如何获得它

A保护API令牌(PAT) 是一种特殊的OAuth2访问令牌,其范围定义为Uma_ 保护。 创建资源服务器时,Keycloak会自动 创建一个角色,Uma_ 保护,用于相应的客户端应用程序,并将其与客户端的服务帐户相关联。

授予的服务帐户Uma_ 保护角色

授予uma_protection角色的服务帐户

资源服务器可以像其他OAuth2访问令牌一样从Keycloak获取PAT。 例如,使用curl:

卷曲-X柱 \
    -H “内容类型: 应用程序/x-www-form-urlencoded” \
    -D' grant _ type = client_credentials & client_id = ${client_id}& client_secret = ${client_secret}'\
    “http:// localhost:8080/auth/realms/${realm_name}/protocol/openid-connect/token”

上面的例子是使用客户凭证授予类型以从服务器获取PAT。 结果,服务器返回类似于以下内容的响应:

{
  访问令牌:${PAT},
  expires_in:300,
  刷新 _ 结果 _ 在:1800,
  刷新令牌:${refresh_token},
  令牌类型:持票人,
  id_token:${d_token},
  不在政策之前:0,
  会话状态:ccea4a55-9aec-4024-b11c-44f6f168439e
}
Keycloak可以通过不同的方式对您的客户端应用程序进行身份验证。 为简单起见,客户凭证此处使用grant类型, 这需要一个客户id和一个客户 _ 秘密。 您可以选择使用任何受支持的身份验证方法。

管理资源

资源服务器可以使用符合UMA的端点远程管理其资源。

http:// $ {主机 }:${ 端口}/auth/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

创建资源

要创建资源,您必须发送HTTP POST请求,如下所示:

卷曲-v -X柱 \
  http:// $ {主机 }:${ 端口}/auth/realms/${realm_name}/authz/protection/resource_set \
  -H '授权: 不记名' $ pat \
  -H' 内容类型: 应用程序/json' \
  -d '{
     “名称”: “Tweedl社会服务”,
     “类型”: “http://www.example.com/rsrcs/socialstream/ 140-兼容”,
     "icon_uri":"http://www.example.com/icons/sharesocial.png",
     “资源范围”: [
         “阅读-公共”,
         “更新后”,
         “私人阅读”,
         “http://www.example.com/scopes/all”
      ]
  }'

默认情况下,资源的所有者是资源服务器。 如果要定义不同的所有者,例如 特定用户,您可以发送如下请求:

卷曲-v -X柱 \
  http:// $ {主机 }:${ 端口}/auth/realms/${realm_name}/authz/protection/resource_set \
  -H '授权: 不记名' $ pat \
  -H' 内容类型: 应用程序/json' \
  -d '{
     “名称”: “爱丽丝资源”,
     “主人”: “爱丽丝”
  }'

财产在哪里所有者可以使用用户名或用户的标识符进行设置。

创建用户管理的资源

默认情况下,通过Protection API创建的资源不能由资源所有者通过用户帐户服务

要创建资源并允许资源所有者管理这些资源,您必须设置所有者管理访问属性如下:

卷曲-v -X柱 \
  http:// $ {主机 }:${ 端口}/auth/realms/${realm_name}/authz/protection/resource_set \
  -H '授权: 不记名' $ pat \
  -H' 内容类型: 应用程序/json' \
  -d '{
     “名称”: “爱丽丝资源”,
     “所有者”: “爱丽丝”,
     “所有者管理访问”: 真
  }'
更新资源

要更新现有资源,请发送HTTP PUT请求,如下所示:

卷曲-v -X放 \
  http:// $ {主机 }:${ 端口}/auth/realms/${realm_name}/authz/protection/resource_set/{resource_id} \
  -H '授权: 不记名' $ pat \
  -H' 内容类型: 应用程序/json' \
  -d '{
     "_Id": "爱丽丝资源",
     “名称”: “爱丽丝资源”,
     “资源范围”: [
        “读”
     ]
  }'
删除资源

要删除现有资源,请发送HTTP删除请求,如下所示:

卷曲-v -X删除 \
  http:// $ {主机 }:${ 端口}/auth/realms/${realm_name}/authz/protection/resource_set/{resource_id} \
  -H '授权: 不记名' $ pat
查询资源

通过以下方式查询资源id,发送HTTP GET请求如下:

http:// $ {主机 }:${ 端口}/auth/realms/${realm_name}/authz/protection/resource_set/{resource_id}

查询给定的资源名称,发送HTTP GET请求如下:

http:// $ {主机 }:${ 端口}/auth/realms/${realm_name}/authz/protection/resource_set?名称 = 爱丽丝资源

查询给定的资源uri,发送HTTP GET请求如下:

http:// $ {主机 }:${ 端口}/auth/realms/${realm_name}/authz/protection/resource_set?uri =/api/爱丽丝

查询给定的资源所有者,发送HTTP GET请求如下:

http:// $ {主机 }:${ 端口}/auth/realms/${realm_name}/authz/protection/resource_set?所有者 = 爱丽丝

查询给定的资源类型,发送HTTP GET请求如下:

http:// $ {主机 }:${ 端口}/auth/realms/${realm_name}/authz/protection/resource_set?类型 = 专辑

查询给定的资源范围,发送HTTP GET请求如下:

http:// $ {主机 }:${ 端口}/auth/realms/${realm_name}/authz/protection/resource_set?范围 = 读取

查询服务器权限时使用参数第一最大结果以限制结果。

管理权限请求

使用UMA协议的资源服务器可以使用特定的端点来管理权限请求。 此端点提供了符合UMA的流程,用于注册权限请求和获取权限票证。

http:// $ {主机 }:${ 端口}/auth/realms/${realm_name}/authz/protection/permission

A权限票是表示权限请求的特殊安全令牌类型。 根据UMA规范,权限票证为:

相关句柄,从授权服务器传送到资源服务器,从资源服务器传送到客户端,并最终从客户端传送回授权服务器,以使授权服务器能够评估正确的策略以应用于对授权数据的请求。

在大多数情况下,您不需要直接处理此端点。 Keycloak提供了一个政策执行者这使UMA为您的 资源服务器,因此它可以从授权服务器获取权限票证,将此票证返回给客户端应用程序,并基于最终请求方令牌 (RPT) 强制执行授权决策。

从Keycloak获取权限票证的过程是由资源服务器执行的,而不是由常规的客户端应用程序执行的, 当客户端尝试访问受保护的资源而无需获得访问资源的必要授权时,会获得权限票证。 发行 使用UMA时,权限票证是一个重要方面,因为它允许资源服务器:

  • 从客户端抽象与资源服务器保护的资源相关联的数据

  • 在Keycloak授权请求中注册,这些请求随后可以在工作流中使用,以根据资源所有者的同意授予访问权限

  • 将资源服务器与授权服务器解耦,并允许它们使用不同的授权服务器保护和管理其资源

就客户而言,许可票还有一些重要方面值得强调:

  • 客户端不需要知道授权数据如何与受保护的资源相关联。 许可票对客户来说是完全不透明的。

  • 客户端可以访问不同资源服务器上的资源,并受到不同授权服务器的保护

这些只是UMA带来的一些好处,其中UMA的其他方面都强烈基于许可票,特别是关于 隐私和用户控制对其资源的访问。

创建权限单

要创建权限票证,请发送HTTP POST请求,如下所示:

卷曲-X柱 \
  http:// $ {主机 }:${ 端口}/auth/realms/${realm_name}/authz/protection/permission \
  -H '授权: 不记名' $ pat \
  -H' 内容类型: 应用程序/json' \
  -d '[
  {
    "资源id": "{资源id}",
    “资源范围”: [
      “查看”
    ]
  }
]'

创建票证时,您还可以推送任意声明,并将这些声明与票证相关联:

卷曲-X柱 \
  http:// $ {主机 }:${ 端口}/auth/realms/${realm_name}/authz/protection/permission \
  -H '授权: 不记名' $ pat \
  -H' 内容类型: 应用程序/json' \
  -d '[
  {
    "资源id": "{资源id}",
    “资源范围”: [
      “查看”
    ],
    “索赔”: {
        “组织”: [“acme”]
    }
  }
]'

在评估关联资源和范围的权限时,这些声明将可用于您的策略 有许可票。

其他不符合UMA的端点
创建权限单

要将id为 {resource_id} 的特定资源的权限授予id为 {user_id} 的用户,作为资源的所有者发送HTTP POST请求,如下所示:

卷曲-X柱 \
     http:// $ {主机 }:${ 端口}/auth/realms/${realm_name}/authz/protection/permission/ticket \
     -H '授权: 承载' $ 访问 _ 令牌 \
     -H' 内容类型: 应用程序/json' \
     -d '{
       "资源": "{资源id}",
       "请求者": "{user_id}",
       “已授予”: 正确,
       “范围名称”: “视图”
     }'
获取许可票
卷曲http:// $ {主机 }:${ 端口}/auth/realms/${realm_name}/authz/保护/权限/票证 \
     -H '授权: 承载' $ access_token

您可以使用这些查询参数中的任何一个:

  • scopeId

  • 资源id

  • 所有者

  • 请求者

  • 授予

  • 返回名称

  • 第一

  • 最大

更新权限单
卷曲-X放 \
     http:// $ {主机 }:${ 端口}/auth/realms/${realm_name}/authz/protection/permission/ticket \
     -H '授权: 承载' $ 访问 _ 令牌 \
     -H' 内容类型: 应用程序/json' \
     -d '{
       "id": "{ticket_id}"
       "资源": "{资源id}",
       "请求者": "{user_id}",
       “已授予”: false,
       “范围名称”: “视图”
     }'
删除权限单
curl -X删除http:// ${host }:${ port}/auth/realms/${realm_name}/authz/protection/permission/ticket_id} \
     -H '授权: 承载' $ access_token

使用策略API管理资源权限

Keycloak利用UMA保护API允许资源服务器管理其用户的权限。 此外 对于资源和权限API,Keycloak提供了一个策略API,可以从该策略API按资源将权限设置为资源 代表其用户的服务器。

策略API可在以下位置获得:

http:// $ {主机 }:${ 端口}/auth/realms/${realm_name}/authz/protection/uma-policy/{资源id}

此API受承载令牌保护,该承载令牌必须表示用户授予资源服务器以代表其管理权限的同意。 承载令牌可以是从 令牌端点使用:

  • 资源所有者密码凭据授予类型

  • 令牌交换,以便将授予某些客户端 (公共客户端) 的访问令牌交换为令牌 其中受众是资源服务器

将权限与资源关联

要将权限与特定资源相关联,您必须发送HTTP POST请求,如下所示:

卷曲-X柱 \
  http:// localhost:8180/auth/realms/photoz/authz/protection/uma-policy/{resource_id} \
  -H '授权: 承载' $ 访问 _ 令牌 \
  -H '缓存控制: 无缓存' \
  -H' 内容类型: 应用程序/json' \
  -d '{
        “姓名”: “任何人经理”,
        “描述”: “允许访问任何人员经理”,
        “范围”: [“阅读”],
        “角色”: [“人员-经理”]
}'

在上面的示例中,我们正在创建并关联对由资源标识哪里 任何具有角色的用户人-经理应该授予阅读范围。

您还可以使用其他访问控制机制 (例如使用组) 创建策略:

卷曲-X柱 \
  http:// localhost:8180/auth/realms/photoz/authz/protection/uma-policy/{resource_id} \
  -H '授权: 承载' $ 访问 _ 令牌 \
  -H '缓存控制: 无缓存' \
  -H' 内容类型: 应用程序/json' \
  -d '{
        “姓名”: “任何人经理”,
        “描述”: “允许访问任何人员经理”,
        “范围”: [“阅读”],
        “组”: [“/经理/人员经理”]
}'

或特定客户:

卷曲-X柱 \
  http:// localhost:8180/auth/realms/photoz/authz/protection/uma-policy/{resource_id} \
  -H '授权: 承载' $ 访问 _ 令牌 \
  -H '缓存控制: 无缓存' \
  -H' 内容类型: 应用程序/json' \
  -d '{
        “姓名”: “任何人经理”,
        “描述”: “允许访问任何人员经理”,
        “范围”: [“阅读”],
        “客户”: [“我的客户”]
}'

或者甚至使用使用JavaScript的自定义策略:

上传脚本是已弃用并将在以后的版本中删除。 默认情况下,此功能被禁用。

启用以启动服务器 -Dkeycloak.profile.feature.upload_scripts = 启用 。 有关更多详细信息,请参见配置文件

卷曲-X柱 \
  http:// localhost:8180/auth/realms/photoz/authz/protection/uma-policy/{resource_id} \
  -H '授权: 承载' $ 访问 _ 令牌 \
  -H '缓存控制: 无缓存' \
  -H' 内容类型: 应用程序/json' \
  -d '{
        “姓名”: “任何人经理”,
        “描述”: “允许访问任何人员经理”,
        “范围”: [“阅读”],
        “条件”: “如果 (isPeopleManager()) {$ evalication.grant()}”
}'

还可以设置这些访问控制机制的任何组合。

要更新现有权限,请发送HTTP PUT请求,如下所示:

卷曲-X放 \
  http:// localhost:8180/auth/realms/photoz/authz/protection/uma-policy/{permission_id} \
  -H '授权: 承载' $ 访问 _ 令牌 \
  -H' 内容类型: 应用程序/json' \
  -d '{
    "id": "21eb3fed-02d7-4b5a-9102-29f3f09b6de2",
    “姓名”: “任何人经理”,
    “描述”: “允许访问任何人员经理”,
    “类型”: “乌玛”,
    “范围”: [
        “专辑: 视图”
    ],
    “逻辑”: “积极”,
    “决策战略”: “一致”,
    "owner": "7e22131a-aa57-4f5f-b1db-6e82babcd322",
    “角色”: [
        “用户”
    ]
}'
删除权限

要删除与资源关联的权限,请发送HTTP删除请求,如下所示:

卷曲-X删除 \
  http:// localhost:8180/auth/realms/photoz/authz/protection/uma-policy/{permission_id} \
  -H '授权: 承载' $ access_token
查询权限

要查询与资源关联的权限,请发送HTTP GET请求,如下所示:

http:// ${host }:${ port}/auth/realms/${realm}/authz/protection/uma-policy?资源 = {资源id}

要查询给定其名称的权限,请发送HTTP GET请求,如下所示:

http:// ${host }:${ port}/auth/realms/${realm}/authz/protection/uma-policy?姓名 = 任何人经理

要查询与特定作用域关联的权限,请发送HTTP GET请求,如下所示:

http:// ${host }:${ port}/auth/realms/${realm}/authz/protection/uma-policy?范围 = 读取

要查询所有权限,请发送HTTP GET请求,如下所示:

http:// ${host }:${ port}/auth/realms/${realm}/authz/protection/uma-policy

查询服务器权限时使用参数第一最大结果以限制结果。

请求方令牌

请求方令牌 (RPT) 是JSON网络令牌 (JWT)数字签名使用JSON网络签名 (JWS)。 令牌是基于Keycloak先前向代表用户的特定客户端发出的OAuth2访问令牌构建的 或者代表它自己。

当您对RPT进行解码时,您会看到类似于以下内容的有效载荷:

{
  授权: {
      权限: [
        {
          资源 _ 集 _ 标识:d2fe9843-6462-4bfc-baba-b5787bb6e0e7,
          资源 _ 集 _ 名称:你好世界资源
        }
      ]
  },
  jti:d6109a09-78fd-4998-bf89-95730dfd0892-1464906679405,
  经验:1464906971,
  nbf:0,
  iat:1464906671,
  潜艇:f1888f4d-5172-4359-be0c-af338505d86c,
  典型:kc_ett,
  azp:你好-世界-authz-服务
}

从该令牌中,您可以从权限索赔。

另请注意,权限与您正在保护的资源/范围直接相关,并且与之完全分离 用于实际授予和颁发这些相同权限的访问控制方法。

反省请求方令牌

有时,您可能需要对请求方令牌 (RPT) 进行内省,以检查其有效性或获取令牌内的权限,以在资源服务器端强制执行授权决策。

令牌内省有两个主要的用例可以帮助你:

  • 当客户端应用程序需要查询令牌有效性以获得具有相同或额外权限的新令牌时

  • 在资源服务器端执行授权决策时,尤其是在没有内置政策执行者适合您的应用

获取有关RPT的信息

象征性的内省本质上是一种OAuth2令牌内省-兼容的端点,您可以从中获取有关RPT的信息。

http:// $ {主机 }:${ 端口}/auth/realms/${realm_name}/协议/openid-connect/token/introspect

要使用此端点对RPT进行内省,您可以向服务器发送请求,如下所示:

卷曲-X柱 \
    -H "授权: 基本aGVsbG8td29ybGQtYXV0aHotc2VydmljZTpzZWNyZXQ =" \
    -H “内容类型: 应用程序/x-www-form-urlencoded” \
    -d '令牌 _ 类型 _ 提示 = 请求 _ 聚会 _ 令牌 & 令牌 = ${RPT}' \
    “http:// localhost:8080/auth/realms/hello-world-authz/protocol/openid-connect/token/introspect”
上面的请求是使用HTTP BASIC并传递客户端的凭据 (客户端ID和secret) 来验证尝试内省令牌的客户端,但是您可以使用Keycloak支持的任何其他客户端身份验证方法。

内省端点期望有两个参数:

  • 令牌 _ 类型 _ 提示

    使用请求 _ 聚会 _ 令牌作为此参数的值,该值指示您要对RPT进行内省。

  • 令牌

    使用服务器在授权过程中返回的令牌字符串作为此参数的值。

结果,服务器响应为:

{
  权限: [
    {
      资源标识:90ccc6fc-b296-4cd1-881e-089e1ee15957,
      资源名称:你好世界资源
    }
  ],
  经验:1465314139,
  nbf:0,
  iat:1465313839,
  澳元:你好-世界-authz-服务,
  活动:
}

如果RPT不是活动的,则返回此响应:

{
  活动:
}

每次要内省RPT时,是否需要调用服务器?

没有。 就像Keycloak服务器发布的常规访问令牌一样,RPTs也使用 JSON网络令牌 (JWT)规格为默认格式。

如果要在不调用远程自省端点的情况下验证这些令牌,则可以对RPT进行解码并在本地查询其有效性。 一旦你解码了令牌, 您还可以使用令牌中的权限来强制执行授权决策。

这基本上就是政策执行者做。 确保:

  • 验证RPT的签名 (基于领域的公钥)

  • 基于its的令牌有效性查询经验,iat,以及澳元索赔

授权客户端Java API

根据您的要求,资源服务器应该能够远程管理资源,甚至可以以编程方式检查权限。 如果您使用的是Java,则可以使用授权客户端API访问Keycloak授权服务。

它针对希望访问服务器提供的不同端点 (例如令牌端点,资源和权限管理端点) 的资源服务器。

Maven依赖

<依赖>
    <依赖>
        <groupId>组织。Keycloak
        <人工制品>Keycloak-authz-客户端</人工制品>
        <版本>${KEYCLOAK_VERSION}</版本>
    </依赖>
</依赖>

配置

客户端配置定义在Keycloak。json文件如下:

{
  境界:你好-世界-作者,
  身份验证-服务器-网址:http:// localhost:8080/auth,
  资源:你好-世界-authz-服务,
  凭据: {
    秘密:秘密
  }
}
  • 境界(必填)

    领域的名称。

  • 身份验证-服务器-网址(必填)

    Keycloak服务器的基本URL。 所有其他Keycloak页面和REST服务端点均由此派生。 它通常是https:// 主机: 端口/身份验证

  • 资源(必填)

    应用程序的客户端id。 每个应用程序都有一个客户端id,用于标识应用程序。

  • 凭据(必填)

    指定应用程序的凭据。 这是一个对象表示法,其中键是凭证类型,值是凭证类型的值。

配置文件通常位于应用程序的类路径中,默认位置是客户端将尝试从其中查找Keycloak。json文件。

创建授权客户端

考虑到你有一个Keycloak。json文件在您的类路径中,您可以创建一个新的AuthzClient实例如下:

    // 根据位于类路径中的keycloak.json中定义的配置创建一个新实例
    AuthzClient authzClient = AuthzClient.create();

获取用户权利

下面是一个示例,说明如何获取用户权利:

// 根据keycloak.json中定义的配置创建新实例
AuthzClient authzClient = AuthzClient.create();

//创建授权请求
授权请求 =新的授权请求 ();

// 将权利请求发送到服务器,以便
// 获取具有授予用户所有权限的RPT
授权响应 = 授权客户端。授权 (爱丽丝,爱丽丝)。授权 (请求);
字符串rpt = 响应.getToken();

系统。输出。打印 (你有一个RPT:+ rpt);

// 现在,您可以使用RPT访问资源服务器上的受保护资源

下面是一个示例,说明如何为一组一个或多个资源获取用户权利:

// 根据keycloak.json中定义的配置创建新实例
AuthzClient authzClient = AuthzClient.create();

//创建授权请求
授权请求 =新的授权请求 ();

// 根据要检查访问权限的资源和范围向请求添加权限
请求。addPermission (默认资源);

// 将权利请求发送到服务器,以便
// 获取具有单个资源权限的RPT
授权响应 = 授权客户端。授权 (爱丽丝,爱丽丝)。授权 (请求);
字符串rpt = 响应.getToken();

系统。输出。打印 (你有一个RPT:+ rpt);

// 现在,您可以使用RPT访问资源服务器上的受保护资源

使用保护API创建资源

// 根据keycloak.json中定义的配置创建新实例
AuthzClient authzClient = AuthzClient.create();

// 使用我们想要的信息创建新的资源表示形式
资源呈现新资源 =新的资源展示 ();

新资源。setName (新资源);
新资源。设置类型 (骨灰盒: 你好-世界-作者: 资源: 示例);

新资源。addScope (新的ScopeRepresentation (骨灰盒: 你好-世界-作者: 范围: 视图));

ProtectedResource resource = authzClient.protection().resource();
Resourcerespresentation existingResource = resourceClient.findByName(newResource.getName());

如果(存在资源!=null) {
    resourceClient.de lete(existingResource.getId());
}

//在服务器上创建资源
Resourcerespresentation响应 = resourceClient.create(newResource);
字符串resourceId = 响应.getId();

// 使用新生成的id查询资源
Resourcerespresentation resource = resourceClient.findById(resourceId);

系统。out.println (资源);

反思RPT

// 根据keycloak.json中定义的配置创建新实例
AuthzClient authzClient = AuthzClient.create();

// 将授权请求发送到服务器,以便
// 获取具有授予用户所有权限的RPT
授权响应 = 授权客户端。授权 (爱丽丝,爱丽丝)。授权 ();
字符串rpt = 响应.getToken();

// 内省令牌
TokenIntrospectionResponse requestingPartyToken = authzClient.protection()。introspectionrequestingpartytoken (rpt);

系统。输出。打印 (令牌状态为:+ requestingPartyToken.getActive());
系统。输出。打印 (服务器授予的权限:);

对于(权限授予: 请求partytoken。获取权限 ()) {
    系统。out.println (已授予);
}

政策执行者

策略执行点 (PEP) 是一种设计模式,因此您可以以不同的方式实现它。 Keycloak提供了所有必要的手段 为不同的平台、环境和编程语言实现PEPs。 Keycloak授权服务提供了一个RESTful API, 并利用OAuth2授权功能使用集中式授权服务器进行细粒度授权。

PEP概述

PEP负责从Keycloak服务器执行访问决策,通过评估策略来做出这些决策 与受保护的资源相关联。 它在您的应用程序中充当过滤器或拦截器,以检查是否特定请求 可以根据这些决定授予的权限来实现受保护的资源。

根据您使用的协议强制执行权限。 当使用UMA时,策略执行者总是按顺序期望RPT作为不记名令牌 决定是否可以送达请求。 这意味着客户端应先从Keycloak获取RPT,然后再向资源服务器发送请求。

但是,如果您不使用UMA,则还可以将常规访问令牌发送到资源服务器。 在这种情况下,策略执行者将尝试直接从服务器获取权限。

如果您使用的是任何Keycloak OIDC适配器,则可以通过将以下属性添加到您的Keycloak。json文件:

Keycloak。json
{
 政策执行者: {}
}

当您启用策略执行者时,发送给您的应用程序的所有请求都将被拦截,并且将授予对受保护资源的访问权限 取决于Keycloak授予发出请求的身份的权限。

策略执行与应用程序的路径和资源您使用Keycloak管理控制台为资源服务器创建的。 默认情况下, 创建资源服务器时,Keycloak会创建一个默认配置对于您的资源服务器,以便您可以快速启用策略实施。

配置

要为您的应用程序启用策略实施,请将以下属性添加到您的Keycloak。json文件:

Keycloak。json
{
  政策执行者: {}
}

或者更详细一点,如果你想手动定义被保护的资源:

{
  政策执行者: {
    用户管理访问: {},
    强制执行-模式:强制执行
    路径: [
      {
        路径:/someUri/*,
        方法: [
          {
            方法:获取,
            范围: [urn:app.com: 范围: 视图]
          },
          {
            方法:邮政,
            范围: [urn:app.com: 范围: 创建]
          }
        ]
      },
      {
        名称:一些资源,
        路径:/使用模式/{id},
        方法: [
          {
            方法:删除,
            范围: [urn:app.com: 范围: 删除]
          }
        ]
      },
      {
        路径:/精确匹配
      },
      {
        名称:管理资源,
        路径:/使用通配符/*
      }
    ]
  }
}

以下是每个配置选项的描述:

  • 政策执行者

    指定定义策略实际执行方式的配置选项,以及您要保护的路径。 如果未指定,则策略执行者会查询服务器 对于与受保护的资源服务器相关联的所有资源。 在这种情况下,您需要确保资源正确配置为Uuri与您要保护的路径匹配的属性。

    • 用户管理访问

      指定适配器使用UMA协议。 如果指定,适配器将根据UMA规范向服务器查询权限票证,并将其返回给客户端。 如果未指定,则策略执行者将能够基于常规访问令牌或rpt来强制执行权限。 在这种情况下, 在令牌缺乏权限时拒绝访问资源之前,策略执行者将尝试直接从服务器获取权限。

    • 强制执行-模式

      指定如何执行策略。

      • 强制执行

        (默认模式) 即使没有与给定资源关联的策略,也会默认拒绝请求。

      • 允许

        即使没有与给定资源关联的策略,也允许请求。

      • 禁用

        完全禁用策略的评估,并允许访问任何资源。 当强制执行-模式禁用 应用程序仍然能够通过授权上下文

    • 拒绝重定向到

      定义一个URL,当从服务器获取 “访问被拒绝” 消息时,客户端请求将被重定向。 默认情况下,适配器以403的HTTP状态码响应。

    • 路径缓存

      定义策略执行者应如何跟踪应用程序中的路径与Keycloak中定义的资源之间的关联。 需要缓存来避免 通过缓存路径和受保护资源之间的关联,向Keycloak服务器发出不必要的请求。

      • 寿命

        定义条目应过期的时间 (以毫秒为单位)。 如果未提供,则默认值为3000。 可以设置等于0的值以完全禁用缓存。 可以设置等于-1的值以禁用缓存的到期。

      • 最大条目

        定义应保留在缓存中的条目的限制。 如果未提供,则默认值为1000

    • 路径

      指定要保护的路径。 此配置是可选的。 如果未定义,策略执行者将通过在Keycloak中获取您定义给应用程序的资源来发现所有路径,这些资源是用Uuri在您的应用程序中表示一些路径。

      • 名称

        服务器上要与给定路径关联的资源的名称。 当与路径,策略执行者会忽略资源的Uuri属性,并使用您提供的路径代替。

      • 路径

        (必填) 相对于应用程序上下文路径的URI。 如果指定了此选项,则策略执行者会向服务器查询具有以下内容的资源:URI具有相同的值。 目前支持一个非常基本的路径匹配逻辑。 有效路径的示例有:

        • 通配符:/*

        • 后缀:/*。html

        • 子路径:/路径/*

        • 路径参数: /resource/{id}

        • 完全匹配:/资源

        • 模式: /{版本}/资源、/api/{版本}/资源/*

      • 方法

        要保护的HTTP方法 (例如,GET,POST,PATCH) 以及它们如何与服务器中给定资源的作用域相关联。

        • 方法

          HTTP方法的名称。

        • 范围

          具有与该方法关联的作用域的字符串数组。 当您将范围与特定方法相关联时,尝试访问受保护资源 (或路径) 的客户端必须提供一个RPT,该RPT授予对列表中指定的所有范围的权限。 例如,如果您定义一个方法邮政有范围创建,RPT必须包含授予对创建执行对路径的POST时的作用域。

        • 范围-实施-模式

          引用与方法关联的作用域的实施模式的字符串。 值可以是全部或者任何。 如果全部, 必须授予所有定义的作用域,才能使用该方法访问资源。 如果任何,至少一个范围应该是 授予以使用该方法访问资源。 默认情况下,强制模式设置为全部

      • 强制执行-模式

        指定如何执行策略。

        • 强制执行

          (默认模式) 即使没有与给定资源关联的策略,也会默认拒绝请求。

        • 禁用

      • 索赔-信息-点

        定义一组必须解决并将其推送到Keycloak服务器的一个或多个声明,以使这些声明可用于策略。 见索赔信息点有关更多详细信息。

    • 惰性加载路径

      指定适配器应如何获取与应用程序中的路径关联的资源的服务器。 如果,政策 enforcer将根据请求的路径相应地按需获取资源。 这个配置特别有用 当您不想在部署期间从服务器获取所有资源时 (如果您没有提供路径) 或以防 您只定义了一个子集路径想按需取人。

    • http-方法-as-scope

      指定范围应如何映射到HTTP方法。 如果设置为,策略执行者将使用HTTP方法从当前请求到 检查是否应授予访问权限。 启用后,请确保Keycloak中的资源与表示要保护的每个HTTP方法的范围相关联。

    • 索赔-信息-点

      定义一组一个或多个全球必须解决并将其推送到Keycloak服务器的声明,以使这些声明可用于策略。 见索赔信息点有关更多详细信息。

索赔信息点

索赔信息点 (CIP) 负责解决索赔并将这些索赔推送到Keycloak服务器 为了提供有关策略访问上下文的更多信息。 它们可以定义为配置选项 为了解决来自不同来源的索赔,例如:

  • HTTP请求 (参数、标头、正文等)

  • 外部HTTP服务

  • 配置中定义的静态值

  • 通过实施索赔信息提供商SPI的任何其他来源

将声明推送到Keycloak服务器时,策略不仅可以基于用户是谁,还可以通过采取 根据给定交易的人,什么,为什么,何时,何地和哪个考虑上下文和内容。 这一切都是关于 基于上下文的授权以及如何使用运行时信息以支持细粒度的授权决策。

从HTTP请求获取信息

以下是几个示例,显示了如何从HTTP请求中提取声明:

Keycloak。json
政策执行者: {
    路径: [
      {
        路径:/受保护/资源,
        索赔-信息-点: {
          索赔: {
            请求请求参数:{请求。参数 ['a']},
            索赔从标题:{请求。标题 ['b']},
            从cookie索赔:{请求。cookie['c']},
            remoteAddr索赔:{请求。远程地址},
            索赔方法:{请求。方法},
            uri索赔:{请求。uri},
            从相对路径索赔:{request.relativePath},
            安全索赔:{请求。安全},
            声明-来自-json-body-object:{请求。正文 ['/a/b/c']},
            声明-来自json-body-array:{请求。正文 ['/d/1']},
            身体索赔:{请求。正文},
            静态值索赔:静态值,
            多个静态值的索赔: [静态,],
            param-replace-multiple-placeholder:测试 {keycloak.access_token['/custom_声明/0']} 和 {request.parameter['a']}
          }
        }
      }
    ]
  }

从外部HTTP服务获取信息

以下是几个示例,显示了如何从外部HTTP服务提取声明:

Keycloak。json
政策执行者: {
    路径: [
      {
        路径:/受保护/资源,
        索赔-信息-点: {
          http: {
            索赔: {
              索赔-a:/a,
              索赔-d:/d,
              claim-d0:/d/0,
              索赔-d-全部: [/d/0,/d/1]
            },
            url:http:// 我的公司/索赔提供商,
            方法:邮政,
            标题: {
              内容类型:应用程序/x-www-表单-urlencoded,
              标题-b: [header-b-value1,header-b-value2],
              授权:承载 {密钥斗篷。访问令牌}
            },
            参数: {
              参数-a: [param-a-value1,param-a-value2],
              参数-主题:{keycloak.access_token['/sub']},
              参数-用户名:{keycloak.access_token['/首选 _ 用户名']},
              参数-其他-索赔:{Keycloak。访问 _ 令牌 ['/自定义 _ 声明']}
            }
          }
        }
      }
    ]
  }

静态索赔

Keycloak。json
政策执行者: {
    路径: [
      {
        路径:/受保护/资源,
        索赔-信息-点: {
          索赔: {
            静态值索赔:静态值,
            多个静态值的索赔: [静态,],
          }
        }
      }
    ]
  }

索赔信息提供商SPI

声明信息提供商SPI可以被开发人员用来支持不同的声明信息点,以防 内置提供商足以满足他们的需求。

例如,要实现新的CIP提供商,您需要实现org.keycloak.适配器.授权.ClaimInformationPointProviderFactoryClaimInformationPointProvider并提供文件META-INF/services/org.keycloak.适配器.授权.ClaimInformationPointProviderFactory 在您的应用程序的类路径中。

示例org.keycloak.适配器.授权.ClaimInformationPointProviderFactory:

公众  我的声明信息点提供工厂 工具ClaimInformationPointProviderFactory <我的claiminformationpointprovider> {

    @ 覆盖
    公众 字符串getName() {
        返回 我的索赔;
    }

    @ 覆盖
    公众 虚空init (政策执行者) {

    }

    @ 覆盖
    公众MyClaimInformationPointProvider创建 (地图<字符串,对象> 配置) {
        返回 新的MyClaimInformationPointProvider (配置);
    }
}

每个CIP提供商都必须与一个名称相关联,如上文中定义的我的claiminformationpointproviderfactory.getName方法。 名字 将用于映射来自索赔-信息-点中的部分政策执行者对实现进行配置。

处理请求时,策略执行者将调用MyClaimInformationPointProviderFactory.create方法,以便获得 MyClaimInformationPointProvider的实例。 调用时,为此特定CIP提供程序定义的任何配置 (通过声明-信息-点) 作为地图传递。

示例ClaimInformationPointProvider:

公众  我的声明信息点提供程序 工具声明信息点提供程序 {

    私人 决赛 地图<字符串,对象> 配置;

    公众ClaimsInformationPointProvider (地图<字符串,对象> 配置) {
        这个。config = config;
    }

    @ 覆盖
    公众 地图<字符串,列表<字符串>> 解决 (HttpFacade httpFacade) {
        地图<字符串,列表<字符串>> 索赔 =新的 HashMap<>();

        // 将您想要的任何声明放入地图

        返回索赔;
    }
}

获取授权上下文

启用策略实施后,从服务器获得的权限可通过组织。Keycloak。授权上下文。 此类提供了几种方法,可用于获取权限并确定是否为特定资源或范围授予了权限。

获取Servlet容器中的授权上下文

    HttpServletRequest请求 =...// 获取javax.servlet.http.HttpServletRequest
    KeycloakSecurityContext keycloakSecurityContext =
        (KeycloakSecurityContext) 请求
            。getAttribute(KeycloakSecurityContext.class.getName());
    授权上下文authzContext =
        keycloakSecurityContext.getAuthorizationContext();
有关如何获得KeycloakSecurityContext咨询适配器配置。 上面的例子应该足够了 在使用Keycloak支持的任何servlet容器运行应用程序时获取上下文。

授权上下文有助于让您更好地控制服务器做出和返回的决策。 例如,您可以使用它 构建动态菜单,根据与资源或范围关联的权限,隐藏或显示项目。

如果(authzContext.hasResourcePermission (项目资源)) {
    // 用户可以访问项目资源
}

如果(authzContext.hasResourcePermission (管理资源)) {
    // 用户可以访问管理资源
}

如果(authzContext.hasScopePermission (urn:project.com: 项目: 创建)) {
    // 用户可以创建新项目
}

授权上下文代表Keycloak授权服务的主要功能之一。 从上面的示例中,您可以看到受保护的资源与管理它们的策略没有直接关联。

考虑使用基于角色的访问控制 (RBAC) 的一些类似代码:

如果(用户。hasRole ('用户')) {
    // 用户可以访问项目资源
}

如果(用户。hasRole ('管理员')) {
    // 用户可以访问管理资源
}

如果(用户。hasRole ('项目经理')) {
    // 用户可以创建新项目
}

尽管两个示例都针对相同的要求,但它们以不同的方式进行。 在RBAC中,仅角色隐含地定义其资源的访问权限。 使用Keycloak,无论您使用的是RBAC、基于属性的访问控制 (ABAC) 还是任何其他BAC变体,您都可以创建更易于管理的代码,这些代码直接关注您的资源。 您具有给定资源或范围的权限,或者没有。

现在,假设您的安全需求已更改,并且除了项目经理之外,PMOs还可以创建新项目。

安全要求会发生变化,但是使用Keycloak无需更改您的应用程序代码即可满足新的要求。 一旦您的应用程序基于资源和范围标识符,您只需更改授权服务器中与特定资源关联的权限或策略的配置。 在这种情况下,与项目资源和/或范围urn:project.com: 项目: 创建会被改变的。

使用AuthorizationContext获取授权客户端实例

授权上下文也可以用来获得对授权客户端API配置到您的应用程序:

    ClientAuthorizationContext clientContext = ClientAuthorizationContext.class.cast(authzContext);
    AuthzClient authzClient = clientContext.getClient();

在某些情况下,受策略执行者保护的资源服务器需要访问授权服务器提供的api。 用一个AuthzClient实例在手中,资源服务器可以与服务器交互,以便以编程方式创建资源或检查特定权限。

JavaScript集成

Keycloak服务器带有一个JavaScript库,您可以使用它与受策略执行者保护的资源服务器进行交互。 该库基于Keycloak JavaScript适配器,可以集成以允许您的客户端从Keycloak服务器获取权限。

您可以从运行的Keycloak服务器实例中获取此库,方法是包括以下内容脚本在您的网页中标记:

<脚本 src=http://.../auth/js/keycloak-authz.js></脚本>

一旦你这样做,你可以创建一个KeycloakAuthorization实例如下:

varKeycloak =...// 从Keycloak.js库获取一个keycloak实例
var授权 =新的KeycloakAuthorization(keycloak);

keycloak-authz.js库提供两个主要功能:

  • 如果要访问受UMA保护的资源服务器,请使用权限票证从服务器获取权限。

  • 通过发送应用程序想要访问的资源和范围,从服务器获取权限。

在这两种情况下,库都允许您轻松地与资源服务器和Keycloak授权服务交互,以获取令牌 客户端可以用作承载令牌来访问资源服务器上受保护资源的权限。

处理来自受UMA保护的资源服务器的授权响应

如果资源服务器受到策略执行者的保护,则它会根据承载令牌所携带的权限来响应客户端请求。 通常,当您尝试使用缺少访问受保护资源的权限的承载令牌访问资源服务器时,资源服务器 用一个401状态代码和WWW-认证头。

HTTP/1.1 401未经授权
WWW-Authenticate: UMA领域 = "$ {领域}",
    as_uri = "https:// ${host }:${ port}/auth/realms/${realm}",
    ticket = "016f84e8-f9b9-11e0-bd6f-0021cc6004de"

UMA授权流程有关更多信息。

您的客户需要做的是从WWW-认证资源服务器返回的头 并使用库发送授权请求如下:

//用权限通知单准备授权请求
var授权请求 = {};
授权请求。票证 = 票证;

// 发送授权请求,如果重试成功
身份。授权 (authorizationRequest)。然后 (函数(rpt) {
    // onGrant
},函数() {
    // onDeny
},函数() {
    // onError
});

授权函数是完全异步的,支持几个回调函数来接收来自服务器的通知:

  • onGrant: 函数的第一个参数。 如果授权成功,并且服务器返回具有请求权限的RPT,则回调将接收RPT。

  • onDeny: 函数的第二个参数。 仅当服务器拒绝了授权请求时才调用。

  • onError: 函数的第三个参数。 仅当服务器响应意外时才调用。

大多数应用程序应该使用onGrant回调以在401响应后重试请求。 后续请求应包括RPT作为重试的承载令牌。

获得权利

keycloak-authz.js图书馆提供了一个权利您可以通过提供从服务器获取RPT的功能 您的客户端想要访问的资源和范围。

关于如何获得具有用户可以访问的所有资源和范围的权限的RPT的示例
授权。权利 ('我的资源服务器id')。然后 (函数(rpt) {
    // onGrant回调函数
    // 如果授权成功,您将收到RPT
    // 具有访问资源服务器的必要权限
});
关于如何获得具有特定资源和范围权限的RPT的示例
授权。权利 ('我的资源服务器',{
    权限: [
        {
            id:一些资源
        }
    ]
})。然后 (函数(rpt) {
    // onGrant
});

当使用权利函数,您必须提供客户id您要访问的资源服务器的。

权利函数是完全异步的,支持几个回调函数来接收来自服务器的通知:

  • onGrant: 函数的第一个参数。 如果授权成功,并且服务器返回具有请求权限的RPT,则回调将接收RPT。

  • onDeny: 函数的第二个参数。 仅当服务器拒绝了授权请求时才调用。

  • onError: 函数的第三个参数。 仅当服务器响应意外时才调用。

授权请求

两者授权权利函数接受授权请求对象。 这个对象可以用以下设置 属性:

  • 权限

    表示资源和范围的对象数组。 例如:

    var授权请求 = {
       权限: [
           {
               id:一些资源,
               范围: [视图,编辑]
           }
       ]
    }
  • 元数据

    一个对象,其属性定义了服务器应如何处理授权请求。

    • 响应 _ 包括 _ 资源 _ 名称

      一个布尔值,向服务器指示资源名称是否应包含在RPT的权限中。 如果为false,则仅资源 包括标识符。

    • 响应 _ 权限 _ 限制

      一个整数N,它定义了RPT可以拥有的权限数量的限制。 当与 rpt参数,RPT中只会保留最后N个请求的权限

  • 提交 _ 请求

    一个布尔值,指示服务器是否应对权限票证引用的资源和范围创建权限请求。 此参数仅在与参数作为UMA授权过程的一部分。

获取RPT

如果您已经使用库提供的任何授权函数获得了RPT,则始终可以从授权对象中获得RPT,如下所示 (假设它已通过前面显示的一种技术进行了初始化):

varrpt = 授权。rpt;

设置TLS/HTTPS

当服务器使用HTTPS时,请确保您的适配器配置如下:

Keycloak。json
{
  信任商店:路径 _ 到 _ 你的 _ 信任 _ 商店,
  信任商店-密码:信任 _ 商店 _ 密码
}

上面的配置使TLS/HTTPS可以访问授权客户端,从而可以访问 Keycloak服务器远程使用HTTPS方案。

强烈建议您在访问Keycloak服务器端点时启用TLS/HTTPS。