第 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-name}",
as_uri="https://${host}:${port}/realms/${realm-name}",
ticket="016f84e8-f9b9-11e0-bd6f-0021cc6004de"
HTTP/1.1 401 Unauthorized
WWW-Authenticate: UMA realm="${realm-name}",
as_uri="https://${host}:${port}/realms/${realm-name}",
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;