6.5. JavaScript 供应商

Red Hat Single Sign-On 能够在运行时执行脚本的功能,以便管理员能够自定义特定的功能:

  • authenticator
  • JavaScript Policy
  • OpenID Connect 协议映射程序
  • SAML 协议映射程序

6.5.1. authenticator

身份验证脚本必须至少提供以下功能之一:authentication (..),它从 Authenticator Authenticatauthenticate(AuthenticationFlowContext)操作(..) 操作(...) 调用,它从 Authenticator the (AuthenticationFlowContext)调用。

自定义 授权器 至少应提供 authenticate (..) 函数。您可以使用代码中的 javax.script.Bindings 脚本。

script
用于访问脚本元数据的 ScriptModel
realm
RealmModel
user
当前 UserModel
会话
active KeycloakSession
authenticationSession
当前 AuthenticationSessionModel
httpRequest
当前 org.jboss.resteasy.spi.HttpRequest
LOG
org.jboss.logging.Logger 限定于 基于脚本的Authenticator
注意

您可以从传递给 验证(context) 操作( context ) 功能的上下文参数中提取其他上下文信息。

AuthenticationFlowError = Java.type("org.keycloak.authentication.AuthenticationFlowError");

function authenticate(context) {

  LOG.info(script.name + " --> trace auth for: " + user.username);

  if (   user.username === "tester"
      && user.getAttribute("someAttribute")
      && user.getAttribute("someAttribute").contains("someValue")) {

      context.failure(AuthenticationFlowError.INVALID_USER);
      return;
  }

  context.success();
}

6.5.2. 使用脚本创建 JAR 以进行部署

注意

JAR 文件是具有 .jar 扩展名的常规 ZIP 文件。

为了使您的脚本可用于 Red Hat Single Sign-On,您需要将其部署到服务器。因此,您应该创建带有以下结构的 JAR 文件:

META-INF/keycloak-scripts.json

my-script-authenticator.js
my-script-policy.js
my-script-mapper.js

META-INF/keycloak-scripts.json 是一个文件描述符,提供关于您要部署的脚本的元数据信息。这是一个带有以下结构的 JSON 文件:

{
    "authenticators": [
        {
            "name": "My Authenticator",
            "fileName": "my-script-authenticator.js",
            "description": "My Authenticator from a JS file"
        }
    ],
    "policies": [
        {
            "name": "My Policy",
            "fileName": "my-script-policy.js",
            "description": "My Policy from a JS file"
        }
    ],
    "mappers": [
        {
            "name": "My Mapper",
            "fileName": "my-script-mapper.js",
            "description": "My Mapper from a JS file"
        }
    ],
    "saml-mappers": [
        {
            "name": "My Mapper",
            "fileName": "my-script-mapper.js",
            "description": "My Mapper from a JS file"
        }
    ]
}

此文件应引用您要部署的不同脚本供应商:

  • authenticators

    对于 OpenID Connect 脚本编写器。您可以在同一 JAR 文件中有一个或多个验证器

  • policies

    对于使用 Red Hat Single Sign-On Authorization 服务时的 JavaScript 策略。您可以在同一 JAR 文件中拥有一个或多个策略

  • 映射程序

    对于 OpenID Connect 脚本映射程序。您可以在同一 JAR 文件中有一个或多个映射程序

  • saml-mappers

    对于 SAML 脚本协议映射程序。您可以在同一 JAR 文件中有一个或多个映射程序

对于 JAR 文件中的每个脚本文件,您需要在 META-INF/keycloak-scripts.json 中对应条目,将您的脚本文件映射到特定的提供程序类型。为此,您应该为每个条目提供以下属性:

  • name

    用于通过 Red Hat Single Sign-On 管理控制台显示脚本的友好名称。如果没有提供,则会改为使用脚本文件的名称

  • description

    最好描述脚本文件的可选文本

  • fileName

    脚本文件的名称。这个属性 是必需的,应映射到 JAR 中的文件。

6.5.3. 部署脚本 JAR

拥有带有描述符和要部署的脚本的 JAR 文件后,您只需将 JAR 复制到 Red Hat Single Sign-On standalone/deployments/ 目录。

6.5.3.1. 在 Java 15 及更高版本上部署脚本引擎

为了运行脚本,Java 应用中需要使用 JavaScript 引擎。Java 14 及较低版本包括 Nashorn JavaScript Engine。它作为 Java 本身和 JavaScript 提供程序的一部分自动提供,默认可以使用此脚本引擎。但是,对于 Java 15 或更高版本,脚本引擎不是 Java 本身的一部分。需要将其添加至您的服务器,因为 Red Hat Single Sign-On 默认没有任何脚本引擎。部署脚本提供者时,Java 15 及更高版本需要额外步骤 - 将您选择的脚本引擎添加到您的发行版中。

您可以使用任何脚本引擎。但是,我们仅使用 Nashorn JavaScript Engine 进行测试。以下步骤假设使用了这个引擎:

您可以通过在 Red Hat Single Sign-On 中添加新模块 nashorn-core 来安装脚本引擎。服务器启动后,您可以在 KEYCLOAK_HOME/bin 目录中运行类似如下的命令:

export NASHORN_VERSION=15.3
wget https://repo1.maven.org/maven2/org/openjdk/nashorn/nashorn-core/$NASHORN_VERSION/nashorn-core-$NASHORN_VERSION.jar
./jboss-cli.sh -c --command="module add --module-root-dir=../modules/system/layers/keycloak/ --name=org.openjdk.nashorn.nashorn-core --resources=./nashorn-core-$NASHORN_VERSION.jar --dependencies=asm.asm,jdk.dynalink"
rm nashorn-core-$NASHORN_VERSION.jar

如果要将供应商安装到不同的模块中,您可以使用默认脚本供应商配置属性 script-engine-module。例如,您可以使用 KEYCLOAK_HOME/standalone/configuration/standalone-*.xml 文件等内容:

<spi name="scripting">
    <provider name="default" enabled="true">
        <properties>
            <property name="script-engine-module" value="org.graalvm.js.js-scriptengine"/>
        </properties>
    </provider>
</spi>