9.5. JavaScript 集成
红帽构建的 Keycloak 服务器附带了一个 JavaScript 库,可用于与策略实施器保护的资源服务器进行交互。这个库基于红帽构建的 Keycloak JavaScript 适配器,可以集成该适配器,以便您的客户端从红帽构建的 Keycloak 服务器获取权限。
您可以通过在网页中包含以下 脚本
标签,从正在运行的红帽构建的 Keycloak Server 实例获取此库:
<script src="http://.../js/keycloak-authz.js"></script>
接下来,您可以创建 KeycloakAuthorization
实例,如下所示:
const keycloak = ... // obtain a Keycloak instance from keycloak.js library const authorization = new KeycloakAuthorization(keycloak);
keycloak-authz.js 库提供两个主要功能:
- 如果您要访问 UMA 保护的资源服务器,请使用权限票据从服务器获取权限。
- 通过发送应用程序想要访问的资源和范围,从服务器获取权限。
在这两种情况下,该程序库都允许您轻松与资源服务器和红帽构建的 Keycloak 授权服务交互,以获取具有您的客户端权限的令牌,作为 bearer 令牌来访问资源服务器上的受保护的资源。
9.5.1. 处理来自 UMA-Protected 资源服务器的授权响应
如果资源服务器受策略执行者保护,它会根据由 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"
如需更多信息,请参阅 UMA 授权过程。
您的客户端需要执行的操作是从资源服务器返回的
标头中提取权限票据,并使用库发送授权请求,如下所示:
WWW-Authenticate
// prepare a authorization request with the permission ticket const authorizationRequest = {}; authorizationRequest.ticket = ticket; // send the authorization request, if successful retry the request Identity.authorization.authorize(authorizationRequest).then(function (rpt) { // onGrant }, function () { // onDeny }, function () { // onError });
授权
功能是完全异步的,支持一些回调功能来从服务器接收通知:
-
onGrant
: 函数的第一个参数。如果授权成功,并且服务器返回具有请求权限的 RPT,则回调会收到 RPT。 -
onDeny
:函数的第二个参数。只有服务器拒绝授权请求时调用。 -
onError
:函数的第三个参数。只有服务器意外响应时才会调用。
大多数应用应使用 onGrant
回调在 401 响应后重试请求。后续请求应包含 RPT,作为重试的 bearer 令牌。
9.5.2. 获取权利
库提供了一个 keycloak-authz.js
权利
功能,您可以通过提供客户端想要访问的资源和范围,从服务器获取 RPT。
有关如何获取具有用户可访问的所有资源和范围权限的 RPT 的示例
authorization.entitlement('my-resource-server-id').then(function (rpt) { // onGrant callback function. // If authorization was successful you'll receive an RPT // with the necessary permissions to access the resource server });
有关如何获取具有特定资源和范围的权限的 RPT 的示例
authorization.entitlement('my-resource-server', { "permissions": [ { "id" : "Some Resource" } ] }).then(function (rpt) { // onGrant });
使用 授权
功能时,您必须提供您要访问的资源服务器的 client_id。
授权
功能是完全异步的,支持一些回调功能来从服务器接收通知:
-
onGrant
: 函数的第一个参数。如果授权成功,并且服务器返回具有请求权限的 RPT,则回调会收到 RPT。 -
onDeny
:函数的第二个参数。只有服务器拒绝授权请求时调用。 -
onError
:函数的第三个参数。只有服务器意外响应时才会调用。
9.5.3. 授权请求
授权
功能都接受授权请求对象。此对象可使用以下属性设置:
和授权
权限
代表资源和范围的对象数组。例如:
const authorizationRequest = { "permissions": [ { "id" : "Some Resource", "scopes" : ["view", "edit"] } ] }
metadata
一个对象,其属性定义服务器应如何处理授权请求。
response_include_resource_name
如果资源名称应包含在 RPT 的权限中,指示到服务器的布尔值。如果为 false,则仅包含资源标识符。
response_permissions_limit
为 RPT 可以具有的权限数量定义限制的整数 N。与
rpt
参数一同使用时,只有最后 N 个请求的权限才会保存在 RPT 中
submit_request
指示服务器是否应该创建权限请求到权限票据引用的资源和范围的布尔值。这个参数仅在与
ticket
参数一起使用时生效,作为 UMA 授权过程的一部分。
9.5.4. 获取 RPT
如果您已使用库提供的任何授权功能获得 RPT,您可以始终从授权对象获取 RPT (假设它已被前面显示的技术之一初始化):
const rpt = authorization.rpt;