5.3. 基于 JavaScript 的策略


警告

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

您可以使用这类策略使用 JavaScript 为权限定义条件。它是红帽单点登录支持的基于规则的策略类型之一,并提供根据 评估 API 编写任何策略的灵活性。

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

注意

默认情况下,JavaScript Policies 无法上传到服务器。您应该希望直接将 JS 策略部署到服务器,如 JavaScript Providers 中所述。

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

Red Hat Single Sign-On 允许您部署 JAR 文件,以将脚本部署到服务器。请参见 JavaScript Providers 以了解更多详情。

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

5.3.2. 例子

5.3.2.1. 从评估上下文中检查属性

以下是基于 JavaScript 的策略的简单示例,它使用基于属性的访问控制(ABAC)根据从执行上下文获取的属性来定义条件:

Copy to Clipboard Toggle word wrap
const context = $evaluation.getContext();
const contextAttributes = context.getAttributes();

if (contextAttributes.containsValue('kc.client.network.ip_address', '127.0.0.1')) {
    $evaluation.grant();
}

5.3.2.2. 从当前身份检查属性

以下是基于 JavaScript 的策略的简单示例,它使用基于属性的访问控制(ABAC)根据与当前身份关联的属性来定义条件:

Copy to Clipboard Toggle word wrap
const context = $evaluation.getContext();
const identity = context.getIdentity();
const attributes = identity.getAttributes();
const email = attributes.getValue('email').asString(0);

if (email.endsWith('@keycloak.org')) {
    $evaluation.grant();
}

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

5.3.2.3. 检查授予当前身份的角色

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

Copy to Clipboard Toggle word wrap
const context = $evaluation.getContext();
const identity = context.getIdentity();

if (identity.hasRealmRole('keycloak_user')) {
    $evaluation.grant();
}

或者,您可以检查用户是否被授予 my-client-role 客户端 角色,其中 my-client 是客户端应用程序的客户端 ID:

Copy to Clipboard Toggle word wrap
const context = $evaluation.getContext();
const identity = context.getIdentity();

if (identity.hasClientRole('my-client', 'my-client-role')) {
    $evaluation.grant();
}

5.3.2.4. 检查授予用户的角色

检查授予用户的域角色:

Copy to Clipboard Toggle word wrap
const realm = $evaluation.getRealm();

if (realm.isUserInRealmRole('marta', 'role-a')) {
    $evaluation.grant();
}

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

Copy to Clipboard Toggle word wrap
const realm = $evaluation.getRealm();

if (realm.isUserInClientRole('marta', 'my-client', 'some-client-role')) {
    $evaluation.grant();
}

5.3.2.5. 检查授予组的角色

检查授予组的域角色:

Copy to Clipboard Toggle word wrap
const realm = $evaluation.getRealm();

if (realm.isGroupInRole('/Group A/Group D', 'role-a')) {
    $evaluation.grant();
}

5.3.2.6. 将任意声明推送到资源服务器

将任意声明推送到资源服务器,以提供有关如何强制实施权限的附加信息:

Copy to Clipboard Toggle word wrap
const permission = $evaluation.getPermission();

// decide if permission should be granted

if (granted) {
    permission.addClaim('claim-a', 'claim-a');
    permission.addClaim('claim-a', 'claim-a1');
    permission.addClaim('claim-b', 'claim-b');
}

5.3.2.7. 检查组成员资格

Copy to Clipboard Toggle word wrap
const realm = $evaluation.getRealm();

if (realm.isUserInGroup('marta', '/Group A/Group B')) {
    $evaluation.grant();
}

5.3.2.8. 混合访问控制机制

您还可以使用多种访问控制机制的组合。以下示例演示了如何在同一策略中使用角色(RBAC)和声明/attributes (ABAC)检查。在这种情况下,我们检查是否被授予 admin 角色,或者具有来自 keycloak.org 域中的电子邮件:

Copy to Clipboard Toggle word wrap
const context = $evaluation.getContext();
const identity = context.getIdentity();
const attributes = identity.getAttributes();
const email = attributes.getValue('email').asString(0);

if (identity.hasRealmRole('admin') || email.endsWith('@keycloak.org')) {
    $evaluation.grant();
}
注意

编写自己的规则时,请记住 $evaluation 对象是实施 org.keycloak.authorization.policy.evaluation.Evaluation 的对象。有关您可以从此接口访问的内容的更多信息,请参阅 评估 API

返回顶部
Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。 了解我们当前的更新.

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

Theme

© 2025 Red Hat, Inc.