8.4. Protection API
Protection API 提供了一组符合 UMA 的端点,提供:
资源管理
使用这个端点,资源服务器可以远程管理其资源,并启用 策略强制 程序查询服务器是否有需要保护的资源。
权限管理
在 UMA 协议中,资源服务器访问此端点以创建权限票据。红帽构建的 Keycloak 还提供端点来管理权限和查询权限的状态。
Policy API
红帽构建的 Keycloak 利用 UMA 保护 API,以允许资源服务器为其用户管理权限。除了 Resource 和 Permission API 外,红帽构建的 Keycloak 提供了一个 Policy API,其中的权限可由其用户的资源服务器设置为资源。
此 API 的一个重要要求是,只允许 资源服务器使用特殊的 OAuth2 访问令牌访问其端点,称为保护 API 令牌(PAT)。在 UMA 中,PAT 是一个具有范围 uma_protection 的令牌。
8.4.1. 什么是 PAT 以及如何获取它 复制链接链接已复制到粘贴板!
保护 API 令牌 (PAT)是一个特殊的 OAuth2 访问令牌,其范围定义为 uma_protection。当您创建资源服务器时,红帽构建的 Keycloak 会自动为对应的客户端应用程序创建一个角色 uma_protection,并将它与客户端的服务帐户关联。
使用 uma_protection 角色授予的服务帐户
与任何其他 OAuth2 访问令牌一样,资源服务器可以从红帽构建的 Keycloak 获取 PAT。例如,使用 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://localhost:8080/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://localhost:8080/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
默认情况下,name
过滤器将匹配任何具有给定模式的资源。要将查询限制为仅返回具有完全匹配的资源,请使用:
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 规格,权限票据是:
从授权服务器传递给资源服务器的关联处理,从资源服务器到客户端,最终从客户端返回到授权服务器,使授权服务器能够评估要应用到授权数据的请求。
在大多数情况下,您不需要直接处理此端点。红帽构建的 Keycloak 提供了一个 策略 保护程序,可为您的资源服务器启用 UMA,以便它可以从授权服务器获取权限票据,将此票据返回到客户端应用程序,并根据最终请求方令牌(RPT)强制实施授权决策。
从红帽构建的 Keycloak 获取权限票据的过程由资源服务器执行,而不是常规客户端应用程序,当客户端试图访问受保护的资源时获取权限票据,而无需必要授予访问资源。使用 UMA 时,权限票据颁发是允许资源服务器的一个重要方面:
- 从与资源服务器保护的资源关联的客户端中提取
- 在红帽构建的 Keycloak 授权请求中注册,之后可在工作流中使用这些请求,根据资源的所有者同意授予访问权限
- 将资源服务器与授权服务器分离,并允许它们使用不同的授权服务器保护和管理其资源
在客户端上,权限票据也有重要方面,需要突出显示:
- 客户端不需要知道授权数据如何与受保护的资源关联。权限票据对客户端完全不透明。
- 客户端可以访问不同资源服务器上的资源,并由不同的授权服务器进行保护
这些只是 UMA 带来了的一些好处,其中 UMA 的其他方面主要基于权限票据,特别是隐私和用户控制对其资源的访问。
8.4.3.1. 创建权限票据 复制链接链接已复制到粘贴板!
要创建权限票据,请发送 HTTP POST 请求,如下所示:
在创建票据时,您还可以推送任意声明,并将这些声明与票据关联:
在评估与权限票据关联的资源和范围的权限时,这些声明将可供您的策略使用。
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 管理资源权限 复制链接链接已复制到粘贴板!
红帽构建的 Keycloak 利用 UMA 保护 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 令牌可以是从令牌端点获取的常规访问令牌:
- 资源所有者密码凭证授予类型
- 令牌交换,用于交换授予某些客户端(公共客户端)的访问令牌,其中 audience 是资源服务器
8.4.4.1. 将权限与资源关联 复制链接链接已复制到粘贴板!
要将权限与特定资源关联,您必须发送 HTTP POST 请求,如下所示:
在上例中,我们将创建新的权限,并将其与 resource_id
代表的资源相关联,其中任何具有角色 person -manager
的用户都应赋予 读
范围。
您还可以使用其他访问控制机制创建策略,如使用组:
或特定客户端:
甚至使用 JavaScript 使用自定义策略:
上传脚本 已弃用,并将在以后的发行版本中删除。此功能默认为禁用。
使用 -Dkeycloak.profile.feature.upload_scripts=enabled
来启用服务器。如需了解更多详细信息,请参阅 启用和禁用功能 章节。
也可以设置这些访问控制机制的任意组合。
要更新现有权限,请发送 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
在查询服务器以获取权限时,首先使用
参数和最大结果来限制结果。