第 2 章 使用 OpenID Connect 来保护应用程序和服务
本节介绍了如何使用 Red Hat Single Sign-On 适配器或通用 OpenID Connect 来保护使用 OpenID Connect 的应用程序和服务。
2.1. Java 适配器
Red Hat Single Sign-On 带有 Java 应用程序的不同适配器范围。选择正确的适配器取决于目标平台。
所有 Java 适配器共享一组常见配置选项,如 Java 适配器配置 章节中所述。
2.1.1. Java adapter 配置
Red Hat Single Sign-On 支持的每个 Java 适配器都可通过简单的 JSON 文件进行配置。这种情况可能如下所示:
{ "realm" : "demo", "resource" : "customer-portal", "realm-public-key" : "MIGfMA0GCSqGSIb3D...31LwIDAQAB", "auth-server-url" : "https://localhost:8443/auth", "ssl-required" : "external", "use-resource-role-mappings" : false, "enable-cors" : true, "cors-max-age" : 1000, "cors-allowed-methods" : "POST, PUT, DELETE, GET", "cors-exposed-headers" : "WWW-Authenticate, My-custom-exposed-Header", "bearer-only" : false, "enable-basic-auth" : false, "expose-token" : true, "verify-token-audience" : true, "credentials" : { "secret" : "234234-234234-234234" }, "connection-pool-size" : 20, "socket-timeout-millis" : 5000, "connection-timeout-millis" : 6000, "connection-ttl-millis" : 500, "disable-trust-manager" : false, "allow-any-hostname" : false, "truststore" : "path/to/truststore.jks", "truststore-password" : "geheim", "client-keystore" : "path/to/client-keystore.jks", "client-keystore-password" : "geheim", "client-key-password" : "geheim", "token-minimum-time-to-live" : 10, "min-time-between-jwks-requests" : 10, "public-key-cache-ttl" : 86400, "redirect-rewrite-rules" : { "^/wsmaster/api/(.*)$" : "/api/$1" } }
您可以将 ${…}
containure 用于系统属性替换。例如: ${jboss.server.config.dir}
替换为 /path/to/Red Hat Single Sign-On
。也支持通过 env
前缀替换环境变量,如 ${env.MY_ENVIRONMENT_VARIABLE}
。
初始配置文件可以从 admin 控制台获得。这可以通过打开 admin 控制台来完成,从菜单中选择 Clients
并单击对应的客户端。打开客户端页面后,点 Installation
选项卡并选择 Keycloak OIDC JSON
。
以下是每个配置选项的描述:
- realm
- 域的名称。这是 REQUIRED.
- resource
- 应用程序的 client-id。每个应用程序都有一个用于标识应用程序的 client-id。这是 REQUIRED.
- realm-public-key
- realm 公钥的 PEM 格式。您可以从 Admin Console 获取它。这是选项,我们不推荐对其进行设置。如果没有设置,则适配器会从红帽单点登录下载,并在需要时总是重新下载(例如,Red Hat Single Sign-On 轮转其密钥)。但是,如果设置了 realm-public-key,则适配器永远不会从 Red Hat Single Sign-On 下载新密钥,因此当红帽单点登录轮转它的密钥时,适配器可能会中断。
- auth-server-url
-
红帽单点登录服务器的基本 URL。所有其他红帽单点登录页面和 REST 服务端点都源自于此。它通常是
https://host:port/auth
格式。这是 REQUIRED. - ssl-required
-
确保所有与 Red Hat Single Sign-On 服务器的通信均通过 HTTPS。在生产环境中,这应设置为
all
。这是 选项。默认值为 external。这意味着外部请求默认需要 HTTPS。有效值为 'all'、'external' 和 'none'。 - confidential-port
- 红帽单点登录服务器用于通过 SSL/TLS 进行安全连接的机密端口。这是 选项。默认值为 8443。
- use-resource-role-mappings
- 如果设置为 true,则适配器会在令牌内部查找用户的应用程序级别的角色映射。如果为 false,它将查看用户角色映射的域级别。这是 选项。默认值为 false。
- public-client
- 如果设置为 true,则适配器不会向 Red Hat Single Sign-On 发送客户端凭证。这是 选项。默认值为 false。
- enable-cors
- 这可实现 CORS 支持。它将处理 CORS preflight 请求。它还将查看访问令牌来确定有效的来源。这是 选项。默认值为 false。
- cors-max-age
-
如果启用了 CORS,这会设置
Access-Control-Max-Age
标头的值。这是 选项。如果没有设置,则这个标头不会在 CORS 响应中返回。 - cors-allowed-methods
-
如果启用了 CORS,这会设置
Access-Control-Allow-Methods
标头的值。这应该是一个用逗号分开的字符串。这是 选项。如果没有设置,则这个标头不会在 CORS 响应中返回。 - cors-allowed-headers
-
如果启用了 CORS,这会设置
Access-Control-Allow-Headers
标头的值。这应该是一个用逗号分开的字符串。这是 选项。如果没有设置,则这个标头不会在 CORS 响应中返回。 - cors-exposed-headers
-
如果启用了 CORS,这会设置
Access-Control-Expose-Headers
标头的值。这应该是一个用逗号分开的字符串。这是 选项。如果没有设置,则这个标头不会在 CORS 响应中返回。 - bearer-only
- 对于服务,这应设为 true。如果启用适配器不会试图验证用户,但只验证 bearer 令牌。这是 选项。默认值为 false。
- 仅自动探测器
-
如果您的应用程序同时充当 Web 应用程序和 Web 服务(如 SOAP 或 REST),则此项应设为 true。它允许您将 Web 应用的未经身份验证的用户重定向到 Red Hat Single Sign-On 登录页面,但向未经身份验证的 SOAP 或 REST 客户端发送 HTTP
401
状态代码,因为它们不知道到登录页面的重定向。红帽单点登录根据典型的标头(如X-Requested-With
、SOAPAction
或Accept
)自动探测 SOAP 或 REST 客户端。默认值为 false。 - enable-basic-auth
- 这告知适配器也支持基本身份验证。如果启用了这个选项,则必须提供 secret。这是 选项。默认值为 false。
- expose-token
-
如果为
true
,则经过身份验证的浏览器客户端(通过 JavaScript HTTP 调用)可以通过 URLroot/k_query_bearer_token
获取签名的访问令牌。这是 选项。默认值为 false。 - credentials
- 指定应用程序的凭证。这是一个对象表示法,其中键是凭证类型,值是凭证类型的值。目前支持 password 和 jwt。这只适用于 具有 "Confidential"访问类型的客户端。
- connection-pool-size
-
此配置选项定义应池与红帽单点登录服务器的连接数量。这是 选项。默认值为
20
。 - socket-timeout-millis
-
在建立连接(以毫秒为单位)后,套接字等待数据的超时。在两个数据包之间不活跃的最大时间。超时值为零将解释为无限超时。负值代表为未定义(如果适用,系统默认值)。默认值为
-1
。这是 选项。 - connection-timeout-millis
-
与远程主机建立连接的超时(以毫秒为单位)。超时值为零将解释为无限超时。负值代表为未定义(如果适用,系统默认值)。默认值为
-1
。这是 选项。 - connection-ttl-millis
-
以毫秒为单位连接客户端到实时的连接时间。小于或等于零的值被解释为无限值。默认值为
-1
。这是 选项。 - disable-trust-manager
-
如果 Red Hat Single Sign-On 服务器需要 HTTPS,且这个配置选项被设置为
true
,则不需要指定信任存储。此设置应只在开发期间使用,永远不会 在生产环境中使用,因为它将禁用 SSL 证书的验证。这是 选项。默认值为false
。 - allow-any-hostname
-
如果 Red Hat Single Sign-On 服务器需要 HTTPS,且该配置选项被设置为
true
,则红帽单点登录服务器的证书通过信任存储进行验证,但不会执行主机名验证。此设置应只在开发期间使用,永远不会 在生产环境中使用,因为它将禁用 SSL 证书的验证。此设置在测试环境中可能很有用,这是 选项。默认值为false
。 - proxy-url
- HTTP 代理的 URL(如果使用)。
- truststore
-
值是信任存储文件的文件路径。如果您使用
classpath:
前缀,则信任存储将从部署的 classpath 获取。用于向 Red Hat Single Sign-On 服务器的传出 HTTPS 通信。进行 HTTPS 请求的客户端需要一种验证它们要通信的服务器主机的方法。这就是信任者的作用。该密钥存储包含一个或多个可信主机证书或证书颁发机构。您可以通过提取红帽单点登录服务器的 SSL 密钥存储的公共证书来创建此信任存储。这是 REQUIRED,除非ssl-required
为none
或disable-trust-manager
为true
。 - truststore-password
-
truststore 的密码。如果设置了
truststore
且信任存储需要密码,则这是 REQUIRED。 - client-keystore
- 这是密钥存储文件的文件路径。当适配器向 Red Hat Single Sign-On 服务器发出 HTTPS 请求时,此密钥存储包含双向 SSL 的客户端证书。这是 选项。
- client-keystore-password
-
客户端密钥存储的密码。如果设置了
client-keystore
,则这是 REQUIRED。 - client-key-password
-
客户端密钥的密码。如果设置了
client-keystore
,则这是 REQUIRED。 - always-refresh-token
- 如果为 true,则适配器将在每个请求中刷新令牌。警告 - 启用后,将导致每个应用程序请求红帽单点登录请求。
- register-node-at-startup
- 如果为 true,则适配器会向红帽单点登录发送注册请求。默认情况下为 false,仅在应用程序集群时使用。详情请参阅 应用程序集群
- register-node-period
- 红帽单点登录重新注册适配器的时间。应用程序集群时会很有用。详情请参阅 应用程序集群
- token-store
- 可能的值有 session 和 cookie。默认为 session,这意味着适配器在 HTTP Session 中存储帐户信息。替代 Cookie 意味着在 cookie 中存储信息。详情请参阅 应用程序集群
- token-cookie-path
- 在使用 cookie 存储时,此选项会设置用于存储帐户信息的 cookie 的路径。如果是一个相对路径,则假定应用程序在上下文根目录中运行,并相对于该上下文 root 进行解释。如果是绝对路径,则使用绝对路径来设置 Cookie 路径。默认使用相对于上下文 root 的路径。
- principal-attribute
-
OpenID Connect ID Token 属性,用于填充 UserPrincipal 名称:如果 token 属性为空,则默认为
sub
。可能的值有sub
,preferred_username
,email
,name
,nickname
,given_name
,family_name
。 - turn-off-change-session-id-on-login
- 在某些平台上成功登录时,会话 ID 被改变,以插入安全攻击向量。如果要关闭此操作,请将此项更改为 true。默认值为 false。
- token-minimum-time-to-live
-
在过期之前,使用 Red Hat Single Sign-On 服务器预先刷新一个活跃的访问令牌的时间(以秒为单位)。当访问令牌发送到另一个 REST 客户端(在评估之前其过期时)时特别有用。这个值不应超过 realm 的访问令牌生命周期span。这是 选项。默认值为
0
秒,因此当访问令牌已过期时,适配器才会刷新访问令牌。 - min-time-between-jwks-requests
-
以秒为单位指定两个请求之间的最短间隔,以便检索新的公钥。默认是 10 秒。当适配器识别带有未知
kid
的令牌时,适配器会始终尝试下载新的公钥。但是,每 10 秒(默认)不会尝试一次。当攻击者使用错误的kid
强制适配器向 Red Hat Single Sign-On 发送大量请求时,为了避免 DoS。 - public-key-cache-ttl
-
以秒为单位,指定两个请求到红帽单点登录之间的最大间隔,以检索新的公钥。默认为 86400 秒(1 天)。当适配器识别带有未知
kid
的令牌时,适配器会始终尝试下载新的公钥。如果它通过已知kid
识别令牌,它仅使用之前下载的公钥。但是,每个配置的时间间隔至少一次(默认为 1 天)是新的公钥,即使kid
of token 已经已知。 - ignore-oauth-query-parameter
-
默认为
false
,如果设为true
,则会关闭处理 bearer 令牌处理的access_token
查询参数。如果用户只通过了access_token
,用户将无法验证 - redirect-rewrite-rules
-
如果需要,指定 Redirect URI 重写规则。这是一个对象表示法,其中键是要匹配重定向 URI 的正则表达式,值是替换 String。
$
字符可用于替换 String 中的反向引用。 - verify-token-audience
-
如果设置为
true
,则在使用 bearer 令牌进行身份验证的过程中,适配器将验证令牌是否包含这个客户端名称(资源)作为使用者。选项对于服务来说,主要服务于由 bearer 令牌验证的请求。这会默认设置为false
,但为了提高安全性,建议启用它。如需了解更多有关受众支持的详细信息,请参阅受众支持。
2.1.2. JBoss EAP 适配器
您可以从 ZIP 文件或从 RPM 安装这个适配器。
2.1.3. 从一个 ZIP 文件安装 JBOSS EAP 适配器
为了保护 JBoss EAP 上部署的 WAR 应用安全,您必须安装并配置 Red Hat Single Sign-On 适配器子系统。然后,有两个选项来保护 WAR。
- 您可以在 WAR 中提供适配器配置文件,并在 web.xml 中将 auth-method 更改为 KEYCLOAK。
-
或者,您不必修改所有 WAR,您可以通过配置文件中的 Red Hat Single Sign-On adapter 子系统配置(如
standalone.xml
)来保护它。
本节都介绍这两种方法。
适配器作为单独的归档提供,具体取决于您使用的服务器版本。
流程
从 软件下载 站点安装适用于您的应用程序服务器的适配器。
在 JBoss EAP 7 上安装:
$ cd $EAP_HOME $ unzip rh-sso-7.6.9-eap7-adapter.zip
此 ZIP 存档包含特定于 Red Hat Single Sign-On 适配器的 JBoss 模块。它还包含用于配置适配器子系统的 JBoss CLI 脚本。
要配置适配器子系统,请执行适当的命令。
如果服务器 没有运行,则在 JBoss EAP 7.1 或更新版本上安装。
$ ./bin/jboss-cli.sh --file=bin/adapter-elytron-install-offline.cli
注意JBoss EAP 6.4 不可用的离线脚本
如果服务器在运行,则在 JBoss EAP 7.1 或更新版本上安装。
$ ./bin/jboss-cli.sh -c --file=bin/adapter-elytron-install.cli
注意在 JBoss EAP 7.1 或更新版本中可以使用旧的非 Elytron 适配器,这意味着您可以使用
adapter-install-offline.cli
注意EAP 分别支持 OpenJDK 17 和 Oracle JDK 17,自 7.4.CP7 和 7.4.CP8。请注意,新的 java 版本使 elytron 变体 compulsory,因此不要使用带有 JDK 17 的传统适配器。另外,在运行适配器 CLI 文件后,执行 EAP 提供的
enable-elytron-se17.cli
脚本。这两个脚本都需要配置 elytron 适配器并删除不兼容的 EAP 子系统。如需了解更多详细信息,请参阅此安全配置更改文章。在 JBoss EAP 6.4 上安装
$ ./bin/jboss-cli.sh -c --file=bin/adapter-install.cli
2.1.3.1. JBoss SSO
JBoss EAP 内置了对部署到同一 JBoss EAP 实例的 Web 应用程序的单点登录支持。使用 Red Hat Single Sign-On 时不应该启用此功能。
2.1.3.2. 保护 WAR
这部分论述了如何通过在 WAR 软件包中添加配置和编辑文件来保护 WAR。
流程
在 WAR 的
WEB-INF
目录下创建一个keycloak.json
适配器配置文件。这个配置文件的格式在 Java 适配器配置 部分中进行了描述。
-
在
web.xml
中将auth-method
设置为KEYCLOAK
。 使用标准 servlet 安全性为您的 URL 指定角色基础限制。
例如:
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <module-name>application</module-name> <security-constraint> <web-resource-collection> <web-resource-name>Admins</web-resource-name> <url-pattern>/admin/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>admin</role-name> </auth-constraint> <user-data-constraint> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> </security-constraint> <security-constraint> <web-resource-collection> <web-resource-name>Customers</web-resource-name> <url-pattern>/customers/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>user</role-name> </auth-constraint> <user-data-constraint> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> </security-constraint> <login-config> <auth-method>KEYCLOAK</auth-method> <realm-name>this is ignored currently</realm-name> </login-config> <security-role> <role-name>admin</role-name> </security-role> <security-role> <role-name>user</role-name> </security-role> </web-app>
2.1.3.3. 通过适配器子系统保护 WAR
您不必修改 WAR 以便使用 Red Hat Single Sign-On 对其进行保护。您也可以通过 Red Hat Single Sign-On Adapter 子系统进行外部保护。虽然您不必将 KEYCLOAK 指定为 auth-method
,但您仍然必须在 web.xml
中定义 security-constraints
。但是,您不必创建 WEB-INF/keycloak.json
文件。元数据改为在 Red Hat Single Sign-On 子系统定义中的服务器配置(standalone.xml
)中定义。
<extensions> <extension module="org.keycloak.keycloak-adapter-subsystem"/> </extensions> <profile> <subsystem xmlns="urn:jboss:domain:keycloak:1.1"> <secure-deployment name="WAR MODULE NAME.war"> <realm>demo</realm> <auth-server-url>http://localhost:8081/auth</auth-server-url> <ssl-required>external</ssl-required> <resource>customer-portal</resource> <credential name="secret">password</credential> </secure-deployment> </subsystem> </profile>
secure-deployment
name
属性标识您要保护的 WAR。其值是 web.xml
中定义的 module-name
,并附加 .war
。其余的配置与在 Java 适配器配置 中定义的 keycloak.json
配置选项对应一个。
例外是 凭证
元素。
为了便于您了解,您可以进入 Red Hat Single Sign-On 管理控制台,并转至与这个 WAR 一致的应用程序的 Client/Installation 选项卡。它提供了一个可以剪切和粘贴的 XML 文件示例。
如果您有多个由同一域保护的部署,您可以在单独的元素中共享域配置。例如:
<subsystem xmlns="urn:jboss:domain:keycloak:1.1"> <realm name="demo"> <auth-server-url>http://localhost:8080/auth</auth-server-url> <ssl-required>external</ssl-required> </realm> <secure-deployment name="customer-portal.war"> <realm>demo</realm> <resource>customer-portal</resource> <credential name="secret">password</credential> </secure-deployment> <secure-deployment name="product-portal.war"> <realm>demo</realm> <resource>product-portal</resource> <credential name="secret">password</credential> </secure-deployment> <secure-deployment name="database.war"> <realm>demo</realm> <resource>database-service</resource> <bearer-only>true</bearer-only> </secure-deployment> </subsystem>
2.1.3.4. 安全域
安全上下文自动传播到 EJB 层。
2.1.4. 从 RPM 安装 JBoss EAP 7 适配器
使用 Red Hat Enterprise Linux 7 时,术语频道被替换为术语仓库。这些说明中,仅使用术语库。
先决条件
在可以从 RPM 安装 JBoss EAP 7 适配器之前,您必须订阅 JBoss EAP 7.4 存储库。
- 确定使用 Red Hat Subscription Manager 将 Red Hat Enterprise Linux 系统注册到您的帐户。如需更多信息,请参阅 Red Hat Subscription Management 文档。
如果您已经订阅了另一个 JBoss EAP 存储库,必须先退出该存储库。
对于 Red Hat Enterprise Linux 6,7:使用 Red Hat Subscription Manager,通过以下命令订阅 JBoss EAP 7.4 存储库。根据您的 Red Hat Enterprise Linux 版本,将 <RHEL_VERSION> 替换为 6 或 7。
$ sudo subscription-manager repos --enable=jb-eap-7-for-rhel-<RHEL_VERSION>-server-rpms
对于 Red Hat Enterprise Linux 8:使用 Red Hat Subscription Manager,使用以下命令订阅 JBoss EAP 7.4 存储库:
$ sudo subscription-manager repos --enable=jb-eap-7.4-for-rhel-8-x86_64-rpms --enable=rhel-8-for-x86_64-baseos-rpms --enable=rhel-8-for-x86_64-appstream-rpms
流程
根据您的 Red Hat Enterprise Linux 版本,为 OIDC 安装 JBoss EAP 7 适配器。
在 Red Hat Enterprise Linux 6 上安装 7:
$ sudo yum install eap7-keycloak-adapter-sso7_6
在 Red Hat Enterprise Linux 8 中安装:
$ sudo dnf install eap7-keycloak-adapter-sso7_6
注意RPM 安装的默认 EAP_HOME 路径为 /opt/rh/eap7/root/usr/share/wildfly。
为 OIDC 模块运行安装脚本。
$ $EAP_HOME/bin/jboss-cli.sh -c --file=$EAP_HOME/bin/adapter-install.cli
您的安装已完成。
2.1.5. 从 RPM 安装 JBoss EAP 6 适配器
使用 Red Hat Enterprise Linux 7 时,术语频道被替换为术语仓库。这些说明中,仅使用术语库。
您必须订阅 JBoss EAP 6 存储库,然后才能从 RPM 安装 EAP 6 适配器。
先决条件
- 确定使用 Red Hat Subscription Manager 将 Red Hat Enterprise Linux 系统注册到您的帐户。如需更多信息,请参阅 Red Hat Subscription Management 文档。
如果您已经订阅了另一个 JBoss EAP 存储库,必须先退出该存储库。
使用 Red Hat Subscription Manager,使用以下命令订阅 JBoss EAP 6 存储库。根据您的 Red Hat Enterprise Linux 版本,将 <RHEL_VERSION> 替换为 6 或 7。
$ sudo subscription-manager repos --enable=jb-eap-6-for-rhel-<RHEL_VERSION>-server-rpms
流程
使用以下命令为 OIDC 安装 EAP 6 适配器:
$ sudo yum install keycloak-adapter-sso7_6-eap6
注意RPM 安装的默认 EAP_HOME 路径为 /opt/rh/eap6/root/usr/share/wildfly。
为 OIDC 模块运行安装脚本。
$ $EAP_HOME/bin/jboss-cli.sh -c --file=$EAP_HOME/bin/adapter-install.cli
您的安装已完成。
2.1.6. JBoss Fuse 6 adapter
Red Hat Single Sign-On 支持保护在 JBoss Fuse 6 中运行的 Web 应用程序。
唯一支持的 Fuse 6 版本是最新的版本。如果您使用早期版本的 Fuse 6,则某些功能可能无法正常工作。特别是 Hawtio 集成将不适用于早期版本的 Fuse 6。
Fuse 支持以下项目的安全性:
- 使用 Pax Web War 扩展程序在 Fuse 上部署的经典 WAR 应用程序
- 使用 Pax Web Whiteboard Extender 在 Fuse 上部署的 servlets
- 使用 Camel Jetty 组件运行的 Apache Camel Jetty 端点
- 在自己的独立 Jetty 引擎上运行 Apache CXF 端点
- CXF servlet 提供的默认引擎上运行的 Apache CXF 端点
- SSH 和 JMX 管理访问权限
- Hawtio 管理控制台
2.1.6.1. 保护 Fuse 6 中的 Web 应用程序
您必须首先安装 Red Hat Single Sign-On Karaf 功能。接下来,您需要根据您要保护的应用程序类型执行这些步骤。所有引用的 Web 应用程序都需要将 Red Hat Single Sign-On Jetty 验证器注入底层 Jetty 服务器。实现此操作的步骤取决于应用程序类型。详情如下所述。
2.1.6.2. 安装 Keycloak 功能
您必须首先在 JBoss Fuse 环境中安装 keycloak
功能。keycloak 功能包括 Fuse 适配器和所有第三方依赖项。您可以从 Maven 存储库或从存档安装它。
2.1.6.2.1. 从 Maven 存储库安装
先决条件
- 您必须在线,并有权访问 Maven 存储库。
对于 Red Hat Single Sign-On,配置适当的 Maven 存储库,以便您可以安装工件。如需更多信息,请参阅 JBoss Enterprise Maven 存储库 页面。
假设 Maven 存储库为 https://maven.repository.redhat.com/ga/,将以下内容添加到
$FUSE_HOME/etc/org.ops4j.pax.url.mvn.cfg
文件中,并将存储库添加到支持的存储库列表中。例如:org.ops4j.pax.url.mvn.repositories= \ https://maven.repository.redhat.com/ga/@id=redhat.product.repo http://repo1.maven.org/maven2@id=maven.central.repo, \ ...
流程
- 启动 JBoss Fuse 6.3.0 Rollup 12
在 Karaf 终端类型中:
features:addurl mvn:org.keycloak/keycloak-osgi-features/18.0.14.redhat-00001/xml/features features:install keycloak
您可能还需要安装 Jetty 9 功能:
features:install keycloak-jetty9-adapter
确保已安装功能:
features:list | grep keycloak
2.1.6.2.2. 从 ZIP 捆绑包安装
如果您离线或者不想使用 Maven 获取 JAR 文件和其他工件,则此安装选项很有用。
流程
- 从 Sotware Downloads 站点下载 Red Hat Single Sign-On Fuse adapter ZIP 存档。
将它解压缩到 JBoss Fuse 的根目录中。然后,依赖项会在
系统
目录下安装。您可以覆盖所有现有 jar 文件。将其用于 JBoss Fuse 6.3.0 Rollup 12:
cd /path-to-fuse/jboss-fuse-6.3.0.redhat-254 unzip -q /path-to-adapter-zip/rh-sso-7.6.9-fuse-adapter.zip
启动 Fuse 并在 fuse/karaf 终端中运行这些命令:
features:addurl mvn:org.keycloak/keycloak-osgi-features/18.0.14.redhat-00001/xml/features features:install keycloak
-
安装对应的 Jetty 适配器。由于工件直接在 JBoss Fuse
系统
目录中提供,因此您不需要使用 Maven 存储库。
2.1.6.3. 保护 Classic WAR 应用程序
流程
在
/WEB-INF/web.xml
文件中,声明必要的:- <security-constraint> 元素中的安全限制
- <login-config> 元素中的登录配置
<security-role> 元素中的安全角色。
例如:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <module-name>customer-portal</module-name> <welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-file-list> <security-constraint> <web-resource-collection> <web-resource-name>Customers</web-resource-name> <url-pattern>/customers/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>user</role-name> </auth-constraint> </security-constraint> <login-config> <auth-method>BASIC</auth-method> <realm-name>does-not-matter</realm-name> </login-config> <security-role> <role-name>admin</role-name> </security-role> <security-role> <role-name>user</role-name> </security-role> </web-app>
将带有验证器的
jetty-web.xml
文件添加到/WEB-INF/jetty-web.xml
文件。例如:
<?xml version="1.0"?> <!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd"> <Configure class="org.eclipse.jetty.webapp.WebAppContext"> <Get name="securityHandler"> <Set name="authenticator"> <New class="org.keycloak.adapters.jetty.KeycloakJettyAuthenticator"> </New> </Set> </Get> </Configure>
-
在 WAR 的
/WEB-INF/
目录中,创建一个新文件 keycloak.json。此配置文件的格式在 Java Adapters Config 部分中进行了描述。也可以使此文件在外部可用,如 配置外部适配器 中所述。 确保您的 WAR 应用程序导入
org.keycloak.adapters.jetty
,并在Import-Package
标头下导入META-INF/MANIFEST.MF
文件中的一些软件包。在项目中使用maven-bundle-plugin
可以正确地生成清单中的 OSGI 标头。请注意,软件包的"*"解析不会导入org.keycloak.adapters.jetty
软件包,因为它不供应用程序或 Blueprint 或 Spring 描述符使用,而是在jetty-web.xml
文件中使用。要导入的软件包列表可能类似如下:
org.keycloak.adapters.jetty;version="18.0.14.redhat-00001", org.keycloak.adapters;version="18.0.14.redhat-00001", org.keycloak.constants;version="18.0.14.redhat-00001", org.keycloak.util;version="18.0.14.redhat-00001", org.keycloak.*;version="18.0.14.redhat-00001", *;resolution:=optional
2.1.6.3.1. 配置外部适配器
如果您不希望 keycloak.json
适配器配置文件捆绑在 WAR 应用程序内,但根据命名约定使外部和加载可用,请使用这个配置方法。
要启用这个功能,请将本节添加到您的 /WEB_INF/web.xml
文件中:
<context-param> <param-name>keycloak.config.resolver</param-name> <param-value>org.keycloak.adapters.osgi.PathBasedKeycloakConfigResolver</param-value> </context-param>
该组件使用 keycloak.config
或 karaf.etc
java 属性来搜索基本文件夹来定位配置。然后,在这些文件夹中搜索一个名为 < your_web_context>-keycloak.json
的文件。
例如,如果您的 Web 应用程序具有上下文 my-portal
,则您的适配器配置会从 $FUSE_HOME/etc/my-portal-keycloak.json
文件加载。
2.1.6.4. 保护部署为 OSGI 服务的 servlet
如果您在 OSGI 捆绑的项目中有一个 servlet 类,但没有部署为典型的 WAR 应用,则可以使用这个方法。Fuse 使用 Pax Web Whiteboard expansioner 来部署如 web 应用程序的 servlet。
流程
Red Hat Single Sign-On 提供
org.keycloak.adapters.osgi.undertow.PaxWebIntegrationService
,它允许注入 jetty-web.xml 并为应用程序配置安全限制。您需要在应用程序的OSGI-INF/blueprint/blueprint.xml
文件中声明这些服务。请注意,您的 servlet 需要依赖于它。配置示例:<?xml version="1.0" encoding="UTF-8"?> <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"> <!-- Using jetty bean just for the compatibility with other fuse services --> <bean id="servletConstraintMapping" class="org.eclipse.jetty.security.ConstraintMapping"> <property name="constraint"> <bean class="org.eclipse.jetty.util.security.Constraint"> <property name="name" value="cst1"/> <property name="roles"> <list> <value>user</value> </list> </property> <property name="authenticate" value="true"/> <property name="dataConstraint" value="0"/> </bean> </property> <property name="pathSpec" value="/product-portal/*"/> </bean> <bean id="keycloakPaxWebIntegration" class="org.keycloak.adapters.osgi.PaxWebIntegrationService" init-method="start" destroy-method="stop"> <property name="jettyWebXmlLocation" value="/WEB-INF/jetty-web.xml" /> <property name="bundleContext" ref="blueprintBundleContext" /> <property name="constraintMappings"> <list> <ref component-id="servletConstraintMapping" /> </list> </property> </bean> <bean id="productServlet" class="org.keycloak.example.ProductPortalServlet" depends-on="keycloakPaxWebIntegration"> </bean> <service ref="productServlet" interface="javax.servlet.Servlet"> <service-properties> <entry key="alias" value="/product-portal" /> <entry key="servlet-name" value="ProductServlet" /> <entry key="keycloak.config.file" value="/keycloak.json" /> </service-properties> </service> </blueprint>
-
您可能需要在项目中具有
WEB-INF
目录(即使您的项目不是 Web 应用程序),并创建/WEB-INF/jetty-web.xml
和/WEB-INF/keycloak.json
文件,如 Classic WAR 应用 部分中所示。请注意,您不需要web.xml
文件,因为蓝图配置文件中声明 security-constraints。
-
您可能需要在项目中具有
META-INF/MANIFEST.MF
中的Import-Package
必须至少包含这些导入:org.keycloak.adapters.jetty;version="18.0.14.redhat-00001", org.keycloak.adapters;version="18.0.14.redhat-00001", org.keycloak.constants;version="18.0.14.redhat-00001", org.keycloak.util;version="18.0.14.redhat-00001", org.keycloak.*;version="18.0.14.redhat-00001", *;resolution:=optional
2.1.6.5. 保护 Apache Camel 应用程序
您可以通过添加带有 KeycloakJettyAuthenticator
的 securityHandler 并注入了正确的安全限制,来保护使用 camel-jetty etty 组件实施的 Apache Camel 端点。您可以使用类似配置将 OSGI-INF/blueprint/blueprint.xml
文件添加到 Camel 应用程序。角色、安全约束映射和 Red Hat Single Sign-On 适配器配置可能会根据您的环境和需求稍有不同。
例如:
<?xml version="1.0" encoding="UTF-8"?> <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:camel="http://camel.apache.org/schema/blueprint" xsi:schemaLocation=" http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd http://camel.apache.org/schema/blueprint http://camel.apache.org/schema/blueprint/camel-blueprint.xsd"> <bean id="kcAdapterConfig" class="org.keycloak.representations.adapters.config.AdapterConfig"> <property name="realm" value="demo"/> <property name="resource" value="admin-camel-endpoint"/> <property name="bearerOnly" value="true"/> <property name="authServerUrl" value="http://localhost:8080/auth" /> <property name="sslRequired" value="EXTERNAL"/> </bean> <bean id="keycloakAuthenticator" class="org.keycloak.adapters.jetty.KeycloakJettyAuthenticator"> <property name="adapterConfig" ref="kcAdapterConfig"/> </bean> <bean id="constraint" class="org.eclipse.jetty.util.security.Constraint"> <property name="name" value="Customers"/> <property name="roles"> <list> <value>admin</value> </list> </property> <property name="authenticate" value="true"/> <property name="dataConstraint" value="0"/> </bean> <bean id="constraintMapping" class="org.eclipse.jetty.security.ConstraintMapping"> <property name="constraint" ref="constraint"/> <property name="pathSpec" value="/*"/> </bean> <bean id="securityHandler" class="org.eclipse.jetty.security.ConstraintSecurityHandler"> <property name="authenticator" ref="keycloakAuthenticator" /> <property name="constraintMappings"> <list> <ref component-id="constraintMapping" /> </list> </property> <property name="authMethod" value="BASIC"/> <property name="realmName" value="does-not-matter"/> </bean> <bean id="sessionHandler" class="org.keycloak.adapters.jetty.spi.WrappingSessionHandler"> <property name="handler" ref="securityHandler" /> </bean> <bean id="helloProcessor" class="org.keycloak.example.CamelHelloProcessor" /> <camelContext id="blueprintContext" trace="false" xmlns="http://camel.apache.org/schema/blueprint"> <route id="httpBridge"> <from uri="jetty:http://0.0.0.0:8383/admin-camel-endpoint?handlers=sessionHandler&matchOnUriPrefix=true" /> <process ref="helloProcessor" /> <log message="The message from camel endpoint contains ${body}"/> </route> </camelContext> </blueprint>
-
META-INF/MANIFEST.MF
中的Import-Package
需要包含以下导入:
javax.servlet;version="[3,4)", javax.servlet.http;version="[3,4)", org.apache.camel.*, org.apache.camel;version="[2.13,3)", org.eclipse.jetty.security;version="[9,10)", org.eclipse.jetty.server.nio;version="[9,10)", org.eclipse.jetty.util.security;version="[9,10)", org.keycloak.*;version="18.0.14.redhat-00001", org.osgi.service.blueprint, org.osgi.service.blueprint.container, org.osgi.service.event,
2.1.6.6. Camel RestDSL
Camel RestDSL 是一个 Camel 功能,用于以流畅的方式定义您的 REST 端点。但是,您仍必须使用特定的实施类,并提供了有关如何与 Red Hat Single Sign-On 集成的说明。
配置集成机制的方法取决于您为其配置 RestDSL 路由的 Camel 组件。
以下示例演示了如何使用 Jetty 组件配置集成,并引用前面 Blueprint 示例中定义的某些 Bean。
<bean id="securityHandlerRest" class="org.eclipse.jetty.security.ConstraintSecurityHandler"> <property name="authenticator" ref="keycloakAuthenticator" /> <property name="constraintMappings"> <list> <ref component-id="constraintMapping" /> </list> </property> <property name="authMethod" value="BASIC"/> <property name="realmName" value="does-not-matter"/> </bean> <bean id="sessionHandlerRest" class="org.keycloak.adapters.jetty.spi.WrappingSessionHandler"> <property name="handler" ref="securityHandlerRest" /> </bean> <camelContext id="blueprintContext" trace="false" xmlns="http://camel.apache.org/schema/blueprint"> <restConfiguration component="jetty" contextPath="/restdsl" port="8484"> <!--the link with Keycloak security handlers happens here--> <endpointProperty key="handlers" value="sessionHandlerRest"></endpointProperty> <endpointProperty key="matchOnUriPrefix" value="true"></endpointProperty> </restConfiguration> <rest path="/hello" > <description>Hello rest service</description> <get uri="/{id}" outType="java.lang.String"> <description>Just an helllo</description> <to uri="direct:justDirect" /> </get> </rest> <route id="justDirect"> <from uri="direct:justDirect"/> <process ref="helloProcessor" /> <log message="RestDSL correctly invoked ${body}"/> <setBody> <constant>(__This second sentence is returned from a Camel RestDSL endpoint__)</constant> </setBody> </route> </camelContext>
2.1.6.7. 在单独的 Jetty 引擎上保护 Apache CXF 端点
流程
要在单独的 Jetty 引擎上运行由 Red Hat Single Sign-On 保护的 CXF 端点,请执行以下步骤。
将
META-INF/spring/beans.xml
添加到应用程序中,并在其中声明httpj:engine-factory
with Jetty SecurityHandler with injectedKeycloakJettyAuthenticator
。CFX JAX-WS 应用的配置可能类似以下:<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:httpj="http://cxf.apache.org/transports/http-jetty/configuration" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi.xsd http://cxf.apache.org/transports/http-jetty/configuration http://cxf.apache.org/schemas/configuration/http-jetty.xsd"> <import resource="classpath:META-INF/cxf/cxf.xml" /> <bean id="kcAdapterConfig" class="org.keycloak.representations.adapters.config.AdapterConfig"> <property name="realm" value="demo"/> <property name="resource" value="custom-cxf-endpoint"/> <property name="bearerOnly" value="true"/> <property name="authServerUrl" value="http://localhost:8080/auth" /> <property name="sslRequired" value="EXTERNAL"/> </bean> <bean id="keycloakAuthenticator" class="org.keycloak.adapters.jetty.KeycloakJettyAuthenticator"> <property name="adapterConfig"> <ref local="kcAdapterConfig" /> </property> </bean> <bean id="constraint" class="org.eclipse.jetty.util.security.Constraint"> <property name="name" value="Customers"/> <property name="roles"> <list> <value>user</value> </list> </property> <property name="authenticate" value="true"/> <property name="dataConstraint" value="0"/> </bean> <bean id="constraintMapping" class="org.eclipse.jetty.security.ConstraintMapping"> <property name="constraint" ref="constraint"/> <property name="pathSpec" value="/*"/> </bean> <bean id="securityHandler" class="org.eclipse.jetty.security.ConstraintSecurityHandler"> <property name="authenticator" ref="keycloakAuthenticator" /> <property name="constraintMappings"> <list> <ref local="constraintMapping" /> </list> </property> <property name="authMethod" value="BASIC"/> <property name="realmName" value="does-not-matter"/> </bean> <httpj:engine-factory bus="cxf" id="kc-cxf-endpoint"> <httpj:engine port="8282"> <httpj:handlers> <ref local="securityHandler" /> </httpj:handlers> <httpj:sessionSupport>true</httpj:sessionSupport> </httpj:engine> </httpj:engine-factory> <jaxws:endpoint implementor="org.keycloak.example.ws.ProductImpl" address="http://localhost:8282/ProductServiceCF" depends-on="kc-cxf-endpoint" /> </beans>
对于 CXF JAX-RS 应用程序,唯一区别可能是取决于 engine-factory 的端点的配置:
<jaxrs:server serviceClass="org.keycloak.example.rs.CustomerService" address="http://localhost:8282/rest" depends-on="kc-cxf-endpoint"> <jaxrs:providers> <bean class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider" /> </jaxrs:providers> </jaxrs:server>
-
META-INF/MANIFEST.MF
中的Import-Package
必须包含这些导入:
META-INF.cxf;version="[2.7,3.2)", META-INF.cxf.osgi;version="[2.7,3.2)";resolution:=optional, org.apache.cxf.bus;version="[2.7,3.2)", org.apache.cxf.bus.spring;version="[2.7,3.2)", org.apache.cxf.bus.resource;version="[2.7,3.2)", org.apache.cxf.transport.http;version="[2.7,3.2)", org.apache.cxf.*;version="[2.7,3.2)", org.springframework.beans.factory.config, org.eclipse.jetty.security;version="[9,10)", org.eclipse.jetty.util.security;version="[9,10)", org.keycloak.*;version="18.0.14.redhat-00001"
2.1.6.8. 在默认的 Jetty Engine 上保护 Apache CXF 端点
某些服务在启动时自动附带部署的 servlet。一个这样的服务是在 http://localhost:8181/cxf 上下文中运行的 CXF servlet。保护此类端点可能比较复杂。目前使用 Red Hat Single Sign-On 的一种方法是 ServletReregistrationService,它在启动时取消了一个内置 servlet,可让您在 Red Hat Single Sign-On 保护的上下文上重新部署。
应用程序中的配置文件 OSGI-INF/blueprint/blueprint.xml
可能类似以下。请注意,它会添加 JAX-RS customerservice
端点,该端点特定于您的应用程序,但更重要的是,可以保护整个 /cxf
上下文。
<?xml version="1.0" encoding="UTF-8"?> <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxrs="http://cxf.apache.org/blueprint/jaxrs" xsi:schemaLocation=" http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd http://cxf.apache.org/blueprint/jaxrs http://cxf.apache.org/schemas/blueprint/jaxrs.xsd"> <!-- JAXRS Application --> <bean id="customerBean" class="org.keycloak.example.rs.CxfCustomerService" /> <jaxrs:server id="cxfJaxrsServer" address="/customerservice"> <jaxrs:providers> <bean class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider" /> </jaxrs:providers> <jaxrs:serviceBeans> <ref component-id="customerBean" /> </jaxrs:serviceBeans> </jaxrs:server> <!-- Securing of whole /cxf context by unregister default cxf servlet from paxweb and re-register with applied security constraints --> <bean id="cxfConstraintMapping" class="org.eclipse.jetty.security.ConstraintMapping"> <property name="constraint"> <bean class="org.eclipse.jetty.util.security.Constraint"> <property name="name" value="cst1"/> <property name="roles"> <list> <value>user</value> </list> </property> <property name="authenticate" value="true"/> <property name="dataConstraint" value="0"/> </bean> </property> <property name="pathSpec" value="/cxf/*"/> </bean> <bean id="cxfKeycloakPaxWebIntegration" class="org.keycloak.adapters.osgi.PaxWebIntegrationService" init-method="start" destroy-method="stop"> <property name="bundleContext" ref="blueprintBundleContext" /> <property name="jettyWebXmlLocation" value="/WEB-INF/jetty-web.xml" /> <property name="constraintMappings"> <list> <ref component-id="cxfConstraintMapping" /> </list> </property> </bean> <bean id="defaultCxfReregistration" class="org.keycloak.adapters.osgi.ServletReregistrationService" depends-on="cxfKeycloakPaxWebIntegration" init-method="start" destroy-method="stop"> <property name="bundleContext" ref="blueprintBundleContext" /> <property name="managedServiceReference"> <reference interface="org.osgi.service.cm.ManagedService" filter="(service.pid=org.apache.cxf.osgi)" timeout="5000" /> </property> </bean> </blueprint>
因此,在默认 CXF HTTP 目标上运行的所有其他 CXF 服务也受到保护。同样,当应用程序取消部署时,整个 /cxf
上下文也会变得不安全。因此,为您的应用程序使用您自己的 Jetty 引擎,如 在单独的 Jetty Engine 上安全 CXF 应用程序 中所述,您可以更好地控制每个应用程序的安全性。
-
WEB-INF
目录可能需要位于您的项目内(即使项目不是 Web 应用)。您可能还需要以类似 Classic WAR 应用 的方式编辑/WEB-INF/jetty-web.xml
和/WEB-INF/keycloak.json
文件。请注意,您不需要web.xml
文件,因为蓝图配置文件中声明安全限制。 -
META-INF/MANIFEST.MF
中的Import-Package
必须包含以下导入:
META-INF.cxf;version="[2.7,3.2)", META-INF.cxf.osgi;version="[2.7,3.2)";resolution:=optional, org.apache.cxf.transport.http;version="[2.7,3.2)", org.apache.cxf.*;version="[2.7,3.2)", com.fasterxml.jackson.jaxrs.json;version="[2.5,3)", org.eclipse.jetty.security;version="[9,10)", org.eclipse.jetty.util.security;version="[9,10)", org.keycloak.*;version="18.0.14.redhat-00001", org.keycloak.adapters.jetty;version="18.0.14.redhat-00001", *;resolution:=optional
2.1.6.9. 保护 Fuse 管理服务
2.1.6.9.1. 使用 SSH 身份验证到 Fuse Terminal
Red Hat Single Sign-On 主要解决 Web 应用程序身份验证的用例;但是,如果您的其他 Web 服务和应用程序通过红帽单点登录保护,则保护非 Web 管理服务(如使用红帽单点登录凭证的 SSH)是最佳选择。您可以使用 JAAS 登录模块进行此操作,该模块允许远程连接到 Red Hat Single Sign-On,并根据 Resource Owner Password 凭据验证凭证。
要启用 SSH 身份验证,请执行以下步骤。
流程
-
在 Red Hat Single Sign-On 中创建一个客户端(例如,
ssh-jmx-admin-client
),它将用于 SSH 身份验证。此客户端需要选择Direct Access Grants Enabled
toOn
。 在
$FUSE_HOME/etc/org.apache.karaf.shell.cfg
文件中,更新或指定此属性:sshRealm=keycloak
添加
$FUSE_HOME/etc/keycloak-direct-access.json
文件,其内容类似于以下内容(基于您的环境和 Red Hat Single Sign-On 客户端设置):{ "realm": "demo", "resource": "ssh-jmx-admin-client", "ssl-required" : "external", "auth-server-url" : "http://localhost:8080/auth", "credentials": { "secret": "password" } }
此文件指定客户端应用程序配置,供
keycloak
JAAS 域中的 JAAS DirectAccessGrantsLoginModule 用于 SSH 身份验证。启动 Fuse 并安装
keycloak
JAAS 域。最简单的方法是安装keycloak-jaas
功能,该功能已预定义了 JAAS 域。您可以使用自己的keycloak
JAAS 域覆盖功能的预定义域。详情请查看 JBoss Fuse 文档。在 Fuse 终端中使用这些命令:
features:addurl mvn:org.keycloak/keycloak-osgi-features/18.0.14.redhat-00001/xml/features features:install keycloak-jaas
在终端中输入以下内容,以
admin
用户身份使用 SSH 登录:ssh -o PubkeyAuthentication=no -p 8101 admin@localhost
-
使用密码
password
登录。
在稍后的一些操作系统中,您可能还需要使用 SSH 命令的 -o 选项 -o HostKeyAlgorithms=+ssh-dss
=+ssh-dss,因为之后的 SSH 客户端不允许使用 ssh-dss
算法。但是,默认情况下,它目前在 JBoss Fuse 6.3.0 Rollup 12 中使用。
请注意,用户需要具有 realm 角色 admin
来执行所有操作或其他角色才能执行操作子集(例如,viewer 角色来限制用户仅运行只读 Karaf 命令)。可用的角色在 $FUSE_HOME/etc/org.apache.karaf.shell.cfg
或 $FUSE_HOME/etc/system.properties
中配置。
2.1.6.9.2. 使用 JMX 身份验证
如果要使用 jconsole 或其他外部工具通过 RMI 远程连接到 JMX,则可能需要使用 JMX 身份验证。否则,最好使用 hawt.io/jolokia,因为 jolokia 代理默认安装在 hawt.io 中。如需了解更多详细信息,请参阅 Hawtio 管理控制台。
流程
在
$FUSE_HOME/etc/org.apache.karaf.management.cfg
文件中,将 jmxRealm 属性更改为:jmxRealm=keycloak
-
安装
keycloak-jaas
功能并配置$FUSE_HOME/etc/keycloak-direct-access.json
文件,如上面的 SSH 部分所述。 - 在 jconsole 中,您可以使用 URL,例如:
service:jmx:rmi://localhost:44444/jndi/rmi://localhost:1099/karaf-root
和凭证:admin/password (基于您环境具有管理员特权的用户)。
2.1.6.10. 保护 Hawtio 管理控制台
要使用红帽单点登录来保护 Hawtio 管理控制台,请执行以下步骤。
流程
将这些属性添加到
$FUSE_HOME/etc/system.properties
文件中:hawtio.keycloakEnabled=true hawtio.realm=keycloak hawtio.keycloakClientConfig=file://${karaf.base}/etc/keycloak-hawtio-client.json hawtio.rolePrincipalClasses=org.keycloak.adapters.jaas.RolePrincipal,org.apache.karaf.jaas.boot.principal.RolePrincipal
-
在域的 Red Hat Single Sign-On 管理控制台中创建客户端。例如,在 Red Hat Single Sign-On
演示
域中,创建一个客户端hawtio-client
,将public
指定为 Access Type,并指定指向 Hawtio: http://localhost:8181/hawtio/* 的重定向 URI。您还必须配置对应的 Web Origin (本例中为 http://localhost:8181)。 -
使用类似以下示例的内容,在
$FUSE_HOME/etc
目录中创建keycloak-hawtio-client.json
文件。根据您的 Red Hat Single Sign-On 环境,更改realm
、resource
和auth-server-url
属性。resource
属性必须指向上一步中创建的客户端。此文件供客户端(Hawtio JavaScript 应用)侧使用。
{ "realm" : "demo", "resource" : "hawtio-client", "auth-server-url" : "http://localhost:8080/auth", "ssl-required" : "external", "public-client" : true }
使用类似以下示例的内容,在
$FUSE_HOME/etc
dicrectory 中创建keycloak-hawtio.json
文件。根据您的 Red Hat Single Sign-On 环境更改realm
和auth-server-url
属性。此文件供服务器(JAAS Login 模块)侧使用。{ "realm" : "demo", "resource" : "jaas", "bearer-only" : true, "auth-server-url" : "http://localhost:8080/auth", "ssl-required" : "external", "use-resource-role-mappings": false, "principal-attribute": "preferred_username" }
启动 JBoss Fuse 6.3.0 Rollup 12 并安装 keycloak 功能(如果您还没有这样做)。Karaf 终端中的命令类似以下示例:
features:addurl mvn:org.keycloak/keycloak-osgi-features/18.0.14.redhat-00001/xml/features features:install keycloak
进入 http://localhost:8181/hawtio,以用户从 Red Hat Single Sign-On 域登录。
请注意,用户需要具有正确的 realm 角色才能成功向 Hawtio 进行身份验证。可用的角色在
hawtio.roles
中的$FUSE_HOME/etc/system.properties
文件中配置。
2.1.6.10.1. 在 JBoss EAP 6.4 上保护 Hawtio
先决条件
设置 Red Hat Single Sign-On,如 保护 Hawtio 管理控制台 中所述。假设:
-
您有一个 Red Hat Single Sign-On realm
demo
和 clienthawtio-client
-
您的 Red Hat Single Sign-On 在
localhost:8080
上运行 -
带有 Hawtio 的 JBoss EAP 6.4 服务器将在
localhost:8181
上运行。此服务器的目录在后续步骤中称为$EAP_HOME
。
流程
-
将
hawtio-wildfly-1.4.0.redhat-630396.war
存档复制到$EAP_HOME/standalone/configuration
目录。有关部署 Hawtio 的详情,请查看 Fuse Hawtio 文档。 -
将带有上述内容的
keycloak-hawtio.json
和keycloak-hawtio-client.json
文件复制到$EAP_HOME/standalone/configuration
目录。 - 将 Red Hat Single Sign-On adapter 子系统安装到 JBoss EAP 6.4 服务器,如 JBoss 适配器文档 所述。
在
$EAP_HOME/standalone/configuration/standalone.xml
文件中,配置系统属性,如下例所示:<extensions> ... </extensions> <system-properties> <property name="hawtio.authenticationEnabled" value="true" /> <property name="hawtio.realm" value="hawtio" /> <property name="hawtio.roles" value="admin,viewer" /> <property name="hawtio.rolePrincipalClasses" value="org.keycloak.adapters.jaas.RolePrincipal" /> <property name="hawtio.keycloakEnabled" value="true" /> <property name="hawtio.keycloakClientConfig" value="${jboss.server.config.dir}/keycloak-hawtio-client.json" /> <property name="hawtio.keycloakServerConfig" value="${jboss.server.config.dir}/keycloak-hawtio.json" /> </system-properties>
将 Hawtio 域添加到
security-domains
部分中的同一文件中:<security-domain name="hawtio" cache-type="default"> <authentication> <login-module code="org.keycloak.adapters.jaas.BearerTokenLoginModule" flag="required"> <module-option name="keycloak-config-file" value="${hawtio.keycloakServerConfig}"/> </login-module> </authentication> </security-domain>
将
secure-deployment
部分hawtio
添加到 adapter 子系统。这样可确保 Hawtio WAR 可以找到 JAAS 登录模块类。<subsystem xmlns="urn:jboss:domain:keycloak:1.1"> <secure-deployment name="hawtio-wildfly-1.4.0.redhat-630396.war" /> </subsystem>
使用 Hawtio 重启 JBoss EAP 6.4 服务器:
cd $EAP_HOME/bin ./standalone.sh -Djboss.socket.binding.port-offset=101
- access Hawtio at http://localhost:8181/hawtio.它通过 Red Hat Single Sign-On 进行保护。
2.1.7. JBoss Fuse 7 Adapter
Red Hat Single Sign-On 支持保护在 JBoss Fuse 7 中运行的 Web 应用程序。
JBoss Fuse 7 利用 Undertow 适配器,与 JBoss EAP 7 适配器相同,JBoss Fuse 7.4.0 与 Undertow HTTP 引擎捆绑在一起,而 Undertow 则用于运行各种 Web 应用。
唯一支持的 Fuse 7 版本是最新的版本。如果您使用早期版本的 Fuse 7,则某些功能可能无法正常工作。特别是,集成不适用于低于 7.12.0 的 Fuse 7 版本。
Fuse 支持以下项目的安全性:
- 使用 Pax Web War 扩展程序在 Fuse 上部署的经典 WAR 应用程序
- 使用 Pax Web Whiteboard Extender 在 Fuse 上部署的 servlets 作为 OSGI 服务,另外通过 org.osgi.service.http.HttpService#registerServlet ()进行注册,它是标准的 OSGi Enterprise HTTP Service
- 使用 Camel Undertow 组件运行的 Apache Camel Undertow 端点
- 在自己的独立 Undertow 引擎上运行 Apache CXF 端点
- CXF servlet 提供的默认引擎上运行的 Apache CXF 端点
- SSH 和 JMX 管理访问权限
- Hawtio 管理控制台
2.1.7.1. 在 Fuse 7 中保护您的 Web 应用程序
您必须首先安装 Red Hat Single Sign-On Karaf 功能。接下来,您需要根据您要保护的应用程序类型执行这些步骤。所有引用的 Web 应用都需要将 Red Hat Single Sign-On Undertow 身份验证机制注入底层 Web 服务器。实现此操作的步骤取决于应用程序类型。详情如下所述。
2.1.7.2. 安装 Keycloak 功能
您必须首先在 JBoss Fuse 环境中安装 keycloak-pax-http-undertow
和 keycloak-jaas
功能。keycloak-pax-http-undertow
功能包括 Fuse 适配器和所有第三方依赖项。keycloak-jaas
包含用于 SSH 和 JMX 身份验证的域中使用的 JAAS 模块。您可以从 Maven 存储库或从存档安装它。
2.1.7.2.1. 从 Maven 存储库安装
先决条件
- 您必须在线,并有权访问 Maven 存储库。
- 对于 Red Hat Single Sign-On,配置适当的 Maven 存储库,以便您可以安装工件。如需更多信息,请参阅 JBoss Enterprise Maven 存储库 页面。
假设 Maven 存储库为 https://maven.repository.redhat.com/ga/,将以下内容添加到
$FUSE_HOME/etc/org.ops4j.pax.url.mvn.cfg
文件中,并将存储库添加到支持的存储库列表中。例如:config:edit org.ops4j.pax.url.mvn config:property-append org.ops4j.pax.url.mvn.repositories ,https://maven.repository.redhat.com/ga/@id=redhat.product.repo config:update feature:repo-refresh
流程
- 启动 JBoss Fuse 7.4.0
在 Karaf 终端中,键入:
feature:repo-add mvn:org.keycloak/keycloak-osgi-features/18.0.14.redhat-00001/xml/features feature:install keycloak-pax-http-undertow keycloak-jaas
您可能还需要安装 Undertow 功能:
feature:install pax-web-http-undertow
确保已安装功能:
feature:list | grep keycloak
2.1.7.2.2. 从 ZIP 捆绑包安装
如果您离线或者不想使用 Maven 获取 JAR 文件和其他工件,这非常有用。
流程
- 从 Sotware Downloads 站点下载 Red Hat Single Sign-On Fuse adapter ZIP 存档。
将它解压缩到 JBoss Fuse 的根目录中。然后,依赖项会在
系统
目录下安装。您可以覆盖所有现有 jar 文件。将其用于 JBoss Fuse 7.4.0 :
cd /path-to-fuse/fuse-karaf-7.z unzip -q /path-to-adapter-zip/rh-sso-7.6.9-fuse-adapter.zip
启动 Fuse 并在 fuse/karaf 终端中运行这些命令:
feature:repo-add mvn:org.keycloak/keycloak-osgi-features/18.0.14.redhat-00001/xml/features feature:install keycloak-pax-http-undertow keycloak-jaas
-
安装对应的 Undertow 适配器。由于工件直接在 JBoss Fuse
系统
目录中提供,因此您不需要使用 Maven 存储库。
2.1.7.3. 保护 Classic WAR 应用程序
流程
在
/WEB-INF/web.xml
文件中,声明必要的:- <security-constraint> 元素中的安全限制
-
<login-config> 元素中的登录配置。确保 <
auth-method>
是KEYCLOAK
。 <security-role> 元素中的安全角色
例如:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <module-name>customer-portal</module-name> <welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-file-list> <security-constraint> <web-resource-collection> <web-resource-name>Customers</web-resource-name> <url-pattern>/customers/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>user</role-name> </auth-constraint> </security-constraint> <login-config> <auth-method>KEYCLOAK</auth-method> <realm-name>does-not-matter</realm-name> </login-config> <security-role> <role-name>admin</role-name> </security-role> <security-role> <role-name>user</role-name> </security-role> </web-app>
在 WAR 的
/WEB-INF/
目录中,创建一个新文件 keycloak.json。此配置文件的格式在 Java Adapters Config 部分中进行了描述。也可以使此文件在外部可用,如 配置外部适配器 中所述。例如:
{ "realm": "demo", "resource": "customer-portal", "auth-server-url": "http://localhost:8080/auth", "ssl-required" : "external", "credentials": { "secret": "password" } }
- 与 Fuse 6 适配器不同,MANIFEST.MF 中不需要特殊的 OSGi 导入。
2.1.7.3.1. 配置解析器
keycloak.json
适配器配置文件可以存储在捆绑包中,该捆绑包是默认的行为,或者存储在文件系统的目录中。要指定配置文件的实际源,请将 keycloak.config.resolver
部署参数设置为所需的配置解析器类。例如,在典型的 WAR 应用程序中,在 web.xml
文件中设置 keycloak.config.resolver
上下文参数,如下所示:
<context-param> <param-name>keycloak.config.resolver</param-name> <param-value>org.keycloak.adapters.osgi.PathBasedKeycloakConfigResolver</param-value> </context-param>
以下解析器可用于 keycloak.config.resolver
:
- org.keycloak.adapters.osgi.BundleBasedKeycloakConfigResolver
-
这是默认的解析器。该配置文件预期在 OSGi 捆绑包内受到保护。默认情况下,它会加载名为
WEB-INF/keycloak.json
的文件,但可通过configLocation
属性配置此文件名。 - org.keycloak.adapters.osgi.PathBasedKeycloakConfigResolver
此解析器在由
keycloak.config
系统属性指定的文件夹中搜索名为 <your_web_context>-keycloak.json
的文件。如果没有设置keycloak.config
,则会使用karaf.etc
系统属性。例如,如果您的 Web 应用程序部署到上下文
my-portal
中,则您的适配器配置将从${keycloak.config}/my-portal-keycloak.json
文件加载,或者从${karaf.etc}/my-portal-keycloak.json
文件加载。- org.keycloak.adapters.osgi.HierarchicalPathBasedKeycloakConfigResolver
这个解析器与上述
PathBasedKeycloakConfigResolver
类似,其中给定 URI 路径,配置位置是从最到最具体的特定检查。例如,对于
/my/web-app/context
URI,会搜索以下配置位置是否存在,直到第一个位置存在:-
${karaf.etc}/my-web-app-context-keycloak.json
-
${karaf.etc}/my-web-app-keycloak.json
-
${karaf.etc}/my-keycloak.json
-
${karaf.etc}/keycloak.json
-
2.1.7.4. 保护部署为 OSGI 服务的 servlet
如果您在 OSGI 捆绑的项目中有一个 servlet 类,但没有部署为典型的 WAR 应用,则可以使用这个方法。Fuse 使用 Pax Web Whiteboard expansioner 来部署如 web 应用程序的 servlet。
流程
Red Hat Single Sign-On 提供
org.keycloak.adapters.osgi.undertow.PaxWebIntegrationService
,它允许为您的应用程序配置身份验证方法和安全限制。您需要在应用程序的OSGI-INF/blueprint/blueprint.xml
文件中声明这些服务。请注意,您的 servlet 需要依赖于它。配置示例:<?xml version="1.0" encoding="UTF-8"?> <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"> <bean id="servletConstraintMapping" class="org.keycloak.adapters.osgi.PaxWebSecurityConstraintMapping"> <property name="roles"> <list> <value>user</value> </list> </property> <property name="authentication" value="true"/> <property name="url" value="/product-portal/*"/> </bean> <!-- This handles the integration and setting the login-config and security-constraints parameters --> <bean id="keycloakPaxWebIntegration" class="org.keycloak.adapters.osgi.undertow.PaxWebIntegrationService" init-method="start" destroy-method="stop"> <property name="bundleContext" ref="blueprintBundleContext" /> <property name="constraintMappings"> <list> <ref component-id="servletConstraintMapping" /> </list> </property> </bean> <bean id="productServlet" class="org.keycloak.example.ProductPortalServlet" depends-on="keycloakPaxWebIntegration" /> <service ref="productServlet" interface="javax.servlet.Servlet"> <service-properties> <entry key="alias" value="/product-portal" /> <entry key="servlet-name" value="ProductServlet" /> <entry key="keycloak.config.file" value="/keycloak.json" /> </service-properties> </service> </blueprint>
您可能需要在项目中具有
WEB-INF
目录(即使您的项目不是 Web 应用程序),并创建/WEB-INF/keycloak.json
文件,如 Classic WAR application 部分所述。请注意,您不需要web.xml
文件,因为蓝图配置文件中声明 security-constraints。- 与 Fuse 6 适配器不同,MANIFEST.MF 中不需要特殊的 OSGi 导入。
2.1.7.5. 保护 Apache Camel 应用程序
您可以通过蓝图注入正确的安全限制并将已使用组件更新至 undertow-keycloak
来保护使用 camel-undertow 组件的 Apache Camel 端点。您必须使用类似配置将 OSGI-INF/blueprint/blueprint.xml
文件添加到 Camel 应用程序。角色、安全约束映射和适配器配置可能会根据您的环境和需求稍有不同。
与标准的 undertow
组件相比,undertow-keycloak
组件添加了两个新属性:
-
configResolver
是一个解析器 bean,提供 Red Hat Single Sign-On 适配器配置。可用的解析器列在 Configuration Resolvers 部分中。 -
allowedRoles
是以逗号分隔的角色列表。访问该服务的用户必须至少具有允许访问的角色。
例如:
<?xml version="1.0" encoding="UTF-8"?> <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:camel="http://camel.apache.org/schema/blueprint" xsi:schemaLocation=" http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd http://camel.apache.org/schema/blueprint http://camel.apache.org/schema/blueprint/camel-blueprint-2.17.1.xsd"> <bean id="keycloakConfigResolver" class="org.keycloak.adapters.osgi.BundleBasedKeycloakConfigResolver" > <property name="bundleContext" ref="blueprintBundleContext" /> </bean> <bean id="helloProcessor" class="org.keycloak.example.CamelHelloProcessor" /> <camelContext id="blueprintContext" trace="false" xmlns="http://camel.apache.org/schema/blueprint"> <route id="httpBridge"> <from uri="undertow-keycloak:http://0.0.0.0:8383/admin-camel-endpoint?matchOnUriPrefix=true&configResolver=#keycloakConfigResolver&allowedRoles=admin" /> <process ref="helloProcessor" /> <log message="The message from camel endpoint contains ${body}"/> </route> </camelContext> </blueprint>
-
META-INF/MANIFEST.MF
中的Import-Package
需要包含以下导入:
javax.servlet;version="[3,4)", javax.servlet.http;version="[3,4)", javax.net.ssl, org.apache.camel.*, org.apache.camel;version="[2.13,3)", io.undertow.*, org.keycloak.*;version="18.0.14.redhat-00001", org.osgi.service.blueprint, org.osgi.service.blueprint.container
2.1.7.6. Camel RestDSL
Camel RestDSL 是一个 Camel 功能,用于以流畅的方式定义您的 REST 端点。但是,您仍必须使用特定的实施类,并提供了有关如何与 Red Hat Single Sign-On 集成的说明。
配置集成机制的方法取决于您为其配置 RestDSL 路由的 Camel 组件。
以下示例演示了如何使用 undertow-keycloak
组件配置集成,并引用前面 Blueprint 示例中定义的一些 Bean。
<camelContext id="blueprintContext" trace="false" xmlns="http://camel.apache.org/schema/blueprint"> <!--the link with Keycloak security handlers happens by using undertow-keycloak component --> <restConfiguration apiComponent="undertow-keycloak" contextPath="/restdsl" port="8484"> <endpointProperty key="configResolver" value="#keycloakConfigResolver" /> <endpointProperty key="allowedRoles" value="admin,superadmin" /> </restConfiguration> <rest path="/hello" > <description>Hello rest service</description> <get uri="/{id}" outType="java.lang.String"> <description>Just a hello</description> <to uri="direct:justDirect" /> </get> </rest> <route id="justDirect"> <from uri="direct:justDirect"/> <process ref="helloProcessor" /> <log message="RestDSL correctly invoked ${body}"/> <setBody> <constant>(__This second sentence is returned from a Camel RestDSL endpoint__)</constant> </setBody> </route> </camelContext>
2.1.7.7. 在单独的 Undertow Engine 上保护 Apache CXF 端点
要在单独的 Undertow 引擎上运行由 Red Hat Single Sign-On 保护的 CXF 端点,请执行以下步骤。
流程
将
OSGI-INF/blueprint/blueprint.xml
添加到应用程序中,并在其中添加类似于 Camel 配置的 正确配置解析器 Bean。在httpu:engine-factory
中,使用 camel 配置声明org.keycloak.adapters.osgi.undertow.CxfKeycloakAuthHandler
处理程序。CFX JAX-WS 应用的配置可能类似以下:<?xml version="1.0" encoding="UTF-8"?> <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/blueprint/jaxws" xmlns:cxf="http://cxf.apache.org/blueprint/core" xmlns:httpu="http://cxf.apache.org/transports/http-undertow/configuration". xsi:schemaLocation=" http://cxf.apache.org/transports/http-undertow/configuration http://cxf.apache.org/schemas/configuration/http-undertow.xsd http://cxf.apache.org/blueprint/core http://cxf.apache.org/schemas/blueprint/core.xsd http://cxf.apache.org/blueprint/jaxws http://cxf.apache.org/schemas/blueprint/jaxws.xsd"> <bean id="keycloakConfigResolver" class="org.keycloak.adapters.osgi.BundleBasedKeycloakConfigResolver" > <property name="bundleContext" ref="blueprintBundleContext" /> </bean> <httpu:engine-factory bus="cxf" id="kc-cxf-endpoint"> <httpu:engine port="8282"> <httpu:handlers> <bean class="org.keycloak.adapters.osgi.undertow.CxfKeycloakAuthHandler"> <property name="configResolver" ref="keycloakConfigResolver" /> </bean> </httpu:handlers> </httpu:engine> </httpu:engine-factory> <jaxws:endpoint implementor="org.keycloak.example.ws.ProductImpl" address="http://localhost:8282/ProductServiceCF" depends-on="kc-cxf-endpoint"/> </blueprint>
对于 CXF JAX-RS 应用程序,唯一区别可能是取决于 engine-factory 的端点的配置:
<jaxrs:server serviceClass="org.keycloak.example.rs.CustomerService" address="http://localhost:8282/rest" depends-on="kc-cxf-endpoint"> <jaxrs:providers> <bean class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider" /> </jaxrs:providers> </jaxrs:server>
-
META-INF/MANIFEST.MF
中的Import-Package
必须包含这些导入:
META-INF.cxf;version="[2.7,3.3)", META-INF.cxf.osgi;version="[2.7,3.3)";resolution:=optional, org.apache.cxf.bus;version="[2.7,3.3)", org.apache.cxf.bus.spring;version="[2.7,3.3)", org.apache.cxf.bus.resource;version="[2.7,3.3)", org.apache.cxf.transport.http;version="[2.7,3.3)", org.apache.cxf.*;version="[2.7,3.3)", org.springframework.beans.factory.config, org.keycloak.*;version="18.0.14.redhat-00001"
2.1.7.8. 在默认的 Undertow Engine 上保护 Apache CXF 端点
某些服务在启动时自动附带部署的 servlet。一个这样的服务是在 http://localhost:8181/cxf 上下文中运行的 CXF servlet。Fuse 的 Pax Web 支持通过配置管理员更改现有上下文。这可用于保护 Red Hat Single Sign-On 的端点。
应用程序中的配置文件 OSGI-INF/blueprint/blueprint.xml
可能类似以下。请注意,它会添加 JAX-RS customerservice
端点,该端点特定于您的应用。
<?xml version="1.0" encoding="UTF-8"?> <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxrs="http://cxf.apache.org/blueprint/jaxrs" xsi:schemaLocation=" http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd http://cxf.apache.org/blueprint/jaxrs http://cxf.apache.org/schemas/blueprint/jaxrs.xsd"> <!-- JAXRS Application --> <bean id="customerBean" class="org.keycloak.example.rs.CxfCustomerService" /> <jaxrs:server id="cxfJaxrsServer" address="/customerservice"> <jaxrs:providers> <bean class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider" /> </jaxrs:providers> <jaxrs:serviceBeans> <ref component-id="customerBean" /> </jaxrs:serviceBeans> </jaxrs:server> </blueprint>
此外,您必须创建 ${karaf.etc}/org.ops4j.pax.web.context-anyName.cfg 文件
。它将被视为由 pax-web-runtime
捆绑包跟踪的工厂 PID 配置。这种配置可能包含与标准 web.xml
的一些属性对应的以下属性:
bundle.symbolicName = org.apache.cxf.cxf-rt-transports-http context.id = default context.param.keycloak.config.resolver = org.keycloak.adapters.osgi.HierarchicalPathBasedKeycloakConfigResolver login.config.authMethod = KEYCLOAK security.cxf.url = /cxf/customerservice/* security.cxf.roles = admin, user
有关配置管理文件中可用属性的完整描述,请参阅 Fuse 文档。以上属性的含义如下:
bundle.symbolicName
andcontext.id
-
在
org.ops4j.pax.web.service.WebContainer
中识别捆绑包及其部署上下文。 context.param.keycloak.config.resolver
-
为捆绑包提供
keycloak.config.resolver
上下文参数的值,与web.xml
中的 classic WARs 相同。在 Configuration Resolvers 部分中描述了可用的解析器。 login.config.authMethod
-
身份验证方法.必须是
KEYCLOAK
。 security.anyName.url
和security.anyName.roles
单个安全约束的属性值,就像在
web.xml
中的security-constraint/web-resource-collection/url-pattern
和security-constraint/auth-constraint/role-name
中设置一样。角色通过逗号和空格分开。anyName
标识符可以是任意的,但必须为同一安全约束的独立属性匹配。注意有些 Fuse 版本包含一个程序漏洞,它要求角色用
", "
(comma 和 single space)分开。确保您使用精确使用此表示法来分隔角色。
META-INF/MANIFEST.MF
中的 Import-Package
必须至少包含这些导入:
javax.ws.rs;version="[2,3)", META-INF.cxf;version="[2.7,3.3)", META-INF.cxf.osgi;version="[2.7,3.3)";resolution:=optional, org.apache.cxf.transport.http;version="[2.7,3.3)", org.apache.cxf.*;version="[2.7,3.3)", com.fasterxml.jackson.jaxrs.json;version="${jackson.version}"
2.1.7.9. 保护 Fuse 管理服务
2.1.7.9.1. 使用 SSH 身份验证到 Fuse Terminal
Red Hat Single Sign-On 主要解决 Web 应用程序身份验证的用例;但是,如果您的其他 Web 服务和应用程序通过红帽单点登录保护,则保护非 Web 管理服务(如使用红帽单点登录凭证的 SSH)是最佳选择。您可以使用 JAAS 登录模块进行此操作,该模块允许远程连接到 Red Hat Single Sign-On,并根据 Resource Owner Password 凭据验证凭证。
要启用 SSH 身份验证,请执行以下步骤。
流程
-
在 Red Hat Single Sign-On 中创建一个客户端(例如,
ssh-jmx-admin-client
),它将用于 SSH 身份验证。此客户端需要选择Direct Access Grants Enabled
toOn
。 在
$FUSE_HOME/etc/org.apache.karaf.shell.cfg
文件中,更新或指定此属性:sshRealm=keycloak
添加
$FUSE_HOME/etc/keycloak-direct-access.json
文件,其内容类似于以下内容(基于您的环境和 Red Hat Single Sign-On 客户端设置):{ "realm": "demo", "resource": "ssh-jmx-admin-client", "ssl-required" : "external", "auth-server-url" : "http://localhost:8080/auth", "credentials": { "secret": "password" } }
此文件指定客户端应用程序配置,供
keycloak
JAAS 域中的 JAAS DirectAccessGrantsLoginModule 用于 SSH 身份验证。启动 Fuse 并安装
keycloak
JAAS 域。最简单的方法是安装keycloak-jaas
功能,该功能已预定义了 JAAS 域。您可以使用自己的keycloak
JAAS 域覆盖功能的预定义域。详情请查看 JBoss Fuse 文档。在 Fuse 终端中使用这些命令:
features:addurl mvn:org.keycloak/keycloak-osgi-features/18.0.14.redhat-00001/xml/features features:install keycloak-jaas
在终端中输入以下内容,以
admin
用户身份使用 SSH 登录:ssh -o PubkeyAuthentication=no -p 8101 admin@localhost
-
使用密码
password
登录。
在稍后的一些操作系统中,您可能还需要使用 SSH 命令的 -o 选项 -o HostKeyAlgorithms=+ssh-dss
=+ssh-dss,因为之后的 SSH 客户端不允许使用 ssh-dss
算法。但是,默认情况下,它目前在 JBoss Fuse 7.4.0 中使用。
请注意,用户需要具有 realm 角色 admin
来执行所有操作或其他角色才能执行操作子集(例如,viewer 角色来限制用户仅运行只读 Karaf 命令)。可用的角色在 $FUSE_HOME/etc/org.apache.karaf.shell.cfg
或 $FUSE_HOME/etc/system.properties
中配置。
2.1.7.9.2. 使用 JMX 身份验证
如果要使用 jconsole 或其他外部工具通过 RMI 远程连接到 JMX,则可能需要使用 JMX 身份验证。否则,最好使用 hawt.io/jolokia,因为 jolokia 代理默认安装在 hawt.io 中。如需了解更多详细信息,请参阅 Hawtio 管理控制台。
要使用 JMX 身份验证,请执行以下步骤。
流程
在
$FUSE_HOME/etc/org.apache.karaf.management.cfg
文件中,将 jmxRealm 属性更改为:jmxRealm=keycloak
-
安装
keycloak-jaas
功能并配置$FUSE_HOME/etc/keycloak-direct-access.json
文件,如上面的 SSH 部分所述。 - 在 jconsole 中,您可以使用 URL,例如:
service:jmx:rmi://localhost:44444/jndi/rmi://localhost:1099/karaf-root
和凭证:admin/password (基于您环境具有管理员特权的用户)。
2.1.7.10. 保护 Hawtio 管理控制台
要使用红帽单点登录来保护 Hawtio 管理控制台,请执行以下步骤。
流程
-
在域的 Red Hat Single Sign-On 管理控制台中创建客户端。例如,在 Red Hat Single Sign-On
演示
域中,创建一个客户端hawtio-client
,将public
指定为 Access Type,并指定指向 Hawtio: http://localhost:8181/hawtio/* 的重定向 URI。配置对应的 Web Origin (本例中为 http://localhost:8181)。设置客户端范围映射,以在hawtio-client
客户端详情的 Scope 选项卡中包括 view-profile 客户端角色。 使用类似以下示例的内容,在
$FUSE_HOME/etc
目录中创建keycloak-hawtio-client.json
文件。根据您的 Red Hat Single Sign-On 环境,更改realm
、resource
和auth-server-url
属性。resource
属性必须指向上一步中创建的客户端。此文件供客户端(Hawtio JavaScript 应用)侧使用。{ "realm" : "demo", "clientId" : "hawtio-client", "url" : "http://localhost:8080/auth", "ssl-required" : "external", "public-client" : true }
使用类似以下示例的内容,在
$FUSE_HOME/etc
目录中创建keycloak-direct-access.json
文件。根据您的红帽单点登录环境更改realm
和url
属性。此文件供 JavaScript 客户端使用。{ "realm" : "demo", "resource" : "ssh-jmx-admin-client", "auth-server-url" : "http://localhost:8080/auth", "ssl-required" : "external", "credentials": { "secret": "password" } }
使用类似以下示例的内容,在
$FUSE_HOME/etc
dicrectory 中创建keycloak-hawtio.json
文件。根据您的 Red Hat Single Sign-On 环境更改realm
和auth-server-url
属性。此文件供服务器(JAAS Login 模块)侧使用。{ "realm" : "demo", "resource" : "jaas", "bearer-only" : true, "auth-server-url" : "http://localhost:8080/auth", "ssl-required" : "external", "use-resource-role-mappings": false, "principal-attribute": "preferred_username" }
启动 JBoss Fuse 7.4.0,安装 Keycloak 功能。然后,在 Karaf 终端中输入:
system:property -p hawtio.keycloakEnabled true system:property -p hawtio.realm keycloak system:property -p hawtio.keycloakClientConfig file://\${karaf.base}/etc/keycloak-hawtio-client.json system:property -p hawtio.rolePrincipalClasses org.keycloak.adapters.jaas.RolePrincipal,org.apache.karaf.jaas.boot.principal.RolePrincipal restart io.hawt.hawtio-war
进入 http://localhost:8181/hawtio,以用户从 Red Hat Single Sign-On 域登录。
请注意,用户需要具有正确的 realm 角色才能成功向 Hawtio 进行身份验证。可用的角色在
hawtio.roles
中的$FUSE_HOME/etc/system.properties
文件中配置。
2.1.8. Spring Boot adapter
Spring Boot Adapter 已被弃用,它不包括在 8.0 及更高版本和更高版本的 RH-SSO 版本中。此适配器将在 RH-SSO 7.x 生命周期中维护。用户应迁移到 Spring Security,以便将其 Spring Boot 应用程序与 RH-SSO 集成。
2.1.8.1. 安装 Spring Boot 适配器
为了保护 Spring Boot 应用程序的安全性,您必须将 Keycloak Spring Boot adapter JAR 添加到应用程序中。然后,您必须通过正常的 Spring Boot 配置(application.properties
)提供一些额外的配置。
Keycloak Spring Boot 适配器利用 Spring Boot 的自动配置,因此所有您需要做的都是将这个适配器 Keycloak Spring Boot starter 添加到项目中。
流程
要使用 Maven 将初学者添加到项目中,请添加到您的依赖项中:
<dependency> <groupId>org.keycloak</groupId> <artifactId>keycloak-spring-boot-starter</artifactId> </dependency>
添加 Adapter BOM 依赖项:
<dependencyManagement> <dependencies> <dependency> <groupId>org.keycloak.bom</groupId> <artifactId>keycloak-adapter-bom</artifactId> <version>18.0.14.redhat-00001</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
目前,以下嵌入式容器被支持,在使用 Starter 时不需要任何额外的依赖项:
- tomcat
- Undertow
- Jetty
2.1.8.2. 配置 Spring Boot Adapter
使用流程将 Spring Boot 应用程序配置为使用 Red Hat Single Sign-On。
流程
您不是
keycloak.json
文件,而是通过正常的 Spring Boot 配置为 Spring Boot 适配器配置域。例如:keycloak.realm = demorealm keycloak.auth-server-url = http://127.0.0.1:8080/auth keycloak.ssl-required = external keycloak.resource = demoapp keycloak.credentials.secret = 11111111-1111-1111-1111-111111111111 keycloak.use-resource-role-mappings = true
您可以通过设置
keycloak.enabled = false
来禁用 Keycloak Spring Boot Adapter(例如在测试中)。-
要配置 Policy Enforcer,与 keycloak.json 不同,请使用
policy-enforcer-config
而不是只是policy-enforcer
。 指定通常在
web.xml
中的 Jakarta EE 安全配置。Spring Boot Adapter 将
login-method
设置为KEYCLOAK
,并在启动时配置security-constraints
。以下是配置示例:keycloak.securityConstraints[0].authRoles[0] = admin keycloak.securityConstraints[0].authRoles[1] = user keycloak.securityConstraints[0].securityCollections[0].name = insecure stuff keycloak.securityConstraints[0].securityCollections[0].patterns[0] = /insecure keycloak.securityConstraints[1].authRoles[0] = admin keycloak.securityConstraints[1].securityCollections[0].name = admin stuff keycloak.securityConstraints[1].securityCollections[0].patterns[0] = /admin
如果您计划将 Spring 应用程序部署为 WAR,则不应使用 Spring Boot Adapter,并将专用适配器用于应用服务器或 servlet 容器。您的 Spring Boot 还应包含 web.xml
文件。
2.1.9. Java servlet 过滤器适配器
如果要在没有选择使用 servlet 过滤器适配器的平台上部署 Java Servlet 应用程序。这个适配器的工作方式与其它适配器不同。您不会在 web.xml 中定义安全限制。反之,您可以使用 Red Hat Single Sign-On servlet 过滤器适配器定义一个过滤器映射来保护您要保护的 url 模式。
Backchannel logout 与标准适配器不同。它将会话 ID 标记为已注销,而不是无效的 HTTP 会话。无法基于会话 ID 使 HTTP 会话无效。
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <module-name>application</module-name> <filter> <filter-name>Keycloak Filter</filter-name> <filter-class>org.keycloak.adapters.servlet.KeycloakOIDCFilter</filter-class> </filter> <filter-mapping> <filter-name>Keycloak Filter</filter-name> <url-pattern>/keycloak/*</url-pattern> <url-pattern>/protected/*</url-pattern> </filter-mapping> </web-app>
在上面的代码段中有两个 url-patterns。/ protected/* 是我们需要保护的文件,而 /keycloak/* url-pattern 处理来自 Red Hat Single Sign-On 服务器的回调。
如果您需要排除配置的 url-patterns
下的一些路径,您可以使用 Filter init-param keycloak.config.skipPattern
配置正则表达式,该正则表达式描述了 keycloak 过滤器应立即委派给 filter-chain。默认情况下不配置 skipPattern。
在没有 context-path
的情况下,与 requestURI
匹配模式。假定上下文路径 /myapp
是一个对 /myapp/index.html
的请求,它会根据跳过特征匹配 /index.html
。
<init-param> <param-name>keycloak.config.skipPattern</param-name> <param-value>^/(path1|path2|path3).*</param-value> </init-param>
请注意,您应该在 Red Hat Single Sign-On Admin 控制台中配置您的客户端,其 Admin URL 指向过滤器的 url-pattern 所涵盖的安全部分。
Admin URL 将回调到 Admin URL,以便执行(如 backchannel logout)的操作。因此,本例中的 Admin URL 应为 http[s]://hostname/{context-root}/keycloak
。
如果您需要自定义会话 ID 映射器,您可以在 Filter init-param keycloak.config.idMapper 中配置类的完全限定名称。会话 ID 映射器是一个映射用户 ID 和会话 ID 的映射程序。默认配置了 org.keycloak.adapters.spi.InMemorySessionIdMapper。
<init-param> <param-name>keycloak.config.idMapper</param-name> <param-value>org.keycloak.adapters.spi.InMemorySessionIdMapper</param-value> </init-param>
Red Hat Single Sign-On 过滤器具有与其他适配器相同的配置参数,但您必须将它们定义为 filter init 参数,而不是上下文参数。
要使用此过滤器,请在 WAR poms 中包括这个 maven 工件:
<dependency> <groupId>org.keycloak</groupId> <artifactId>keycloak-servlet-filter-adapter</artifactId> <version>18.0.14.redhat-00001</version> </dependency>
2.1.10. 安全上下文
如果您需要直接访问令牌,可以使用 KeycloakSecurityContext
接口。如果您要从令牌(如用户配置集信息)检索其他详细信息,或者您想要调用受 Red Hat Single Sign-On 保护的 RESTful 服务,这可能很有用。
在 servlet 环境中,它作为 HttpServletRequest 中的属性在安全调用中可用:
httpServletRequest .getAttribute(KeycloakSecurityContext.class.getName());
或者,它位于 HttpSession 中不安全的请求:
httpServletRequest.getSession() .getAttribute(KeycloakSecurityContext.class.getName());
2.1.11. 错误处理
Red Hat Single Sign-On 对基于 servlet 的客户端适配器有一些错误处理功能。在身份验证过程中遇到错误时,红帽 Single Sign-On 将调用 HttpServletResponse.sendError()
。您可以在 web.xml
文件中设置一个错误页面来处理错误。红帽单点登录可以抛出 400、401、403 和 500 错误。
<error-page> <error-code>403</error-code> <location>/ErrorHandler</location> </error-page>
Red Hat Single Sign-On 还设置可检索的 HttpServletRequest
属性。属性名称是 org.keycloak.adapters.spi.AuthenticationError
,它应该被转换为 org.keycloak.adapters.OIDCAuthenticationError
。
例如:
import org.keycloak.adapters.OIDCAuthenticationError; import org.keycloak.adapters.OIDCAuthenticationError.Reason; ... OIDCAuthenticationError error = (OIDCAuthenticationError) httpServletRequest .getAttribute('org.keycloak.adapters.spi.AuthenticationError'); Reason reason = error.getReason(); System.out.println(reason.name());
2.1.12. 退出
您可以通过多种方式从 Web 应用程序注销。对于 Jakarta EE servlet 容器,您可以调用 HttpServletRequest.logout()
。对于其他浏览器应用,您可以将浏览器重定向到 http://auth-server/auth/realms/{realm-name}/protocol/openid-connect/logout
,如果用户使用其浏览器具有 SSO 会话,则将用户注销。当用户确认注销后,会进行实际注销。您可以选择包含 id_token_hint
、post_logout_redirect_uri
、client_id
等参数,如 OpenID Connect RP-Initiated Logout 中所述。因此,如果您在包含 id_token_hint
参数时,用户不需要显式确认该注销。注销后,只要提供用户,用户会自动重定向到指定的 post_logout_redirect_uri
。请注意,在包含 post_logout_redirect_uri
时,您需要包含 client_id
或 id_token_hint
参数。
如果您想避免在注销过程中注销外部身份提供程序,您可以提供 启动_idp 的参数
,并成为身份提供程序的身份(别名)问题。当作为外部身份提供程序发起的单个注销端点的一部分调用时,此参数很有用。initiated ing_idp
是 Red Hat Single Sign-On logout 端点的支持参数,除了 RP-Initiated Logout 规范中描述的参数之外。
当使用 HttpServletRequest.logout()
选项时,适配器对通过刷新令牌的红帽单点登录服务器执行后端 POST 调用。如果从未保护的页面(没有检查有效令牌的页面)执行方法,则刷新令牌将不可用,在这种情况下,适配器会跳过调用。因此,建议使用一个受保护的页面来执行 HttpServletRequest.logout()
,以便在需要时执行当前的令牌,并与红帽单点登录服务器交互。
2.1.13. 参数转发
Red Hat Single Sign-On 初始授权端点请求支持不同的参数。大多数参数都在 OIDC 规格 中所述。某些参数由基于适配器配置自动添加。但是,每个调用时还可添加一些参数。当您打开受保护的应用程序 URI 时,特定的参数将转发到 Red Hat Single Sign-On 授权端点。
例如,如果请求离线令牌,您可以使用 scope
参数打开受保护的应用程序 URI:
http://myappserver/mysecuredapp?scope=offline_access
参数 scope=offline_access
将自动转发到 Red Hat Single Sign-On 授权端点。
支持的参数有:
-
范围 - 使用以空格分隔的范围列表。空格分隔的列表通常是指特定 客户端上定义的客户端范围。请注意,范围
openid
将始终添加到适配器的范围列表中。例如,如果您输入范围选项地址电话
,则到 Red Hat Single Sign-On 的请求将包含 scope 参数scope=openid 地址电话
。 提示 - Red Hat Single Sign-On 支持这些设置:
-
login
- SSO 将会被忽略,并且始终会显示红帽单点登录登录页面,即使用户已经通过身份验证 -
consent
- 只适用于带有Consent Required
的客户端。如果使用它,则 Consent 页面将始终显示,即使用户之前授予了这个客户端的同意。 -
none
- 不显示登录页面;相反,如果用户还没有通过身份验证,该用户将被重定向到应用。此设置允许您在应用程序一侧创建 filter/interceptor,并向用户显示自定义错误页面。请参阅规格中的更多详情。
-
-
max_age - 仅在用户已通过身份验证时才使用。指定验证可保留的最大允许时间,从用户验证身份衡量。如果用户进行身份验证的时间超过
maxAge
,则 SSO 将被忽略,必须重新验证。 - login_hint - 用来预先填充登录表单上的用户名/电子邮件字段。
- kc_idp_hint - 用来告知 Red Hat Single Sign-On 跳过显示登录页面并自动重定向到指定的身份提供程序。身份提供程序文档中的更多信息。
大多数参数都包括在 OIDC 规格。唯一的例外是参数 kc_idp_hint
,它特定于 Red Hat Single Sign-On,并包含要使用的身份提供程序的名称。如需更多信息,请参阅《 服务器管理指南》 中的 Identity Brokering
章节。
如果您使用附加参数打开 URL,如果应用程序中已经通过身份验证,则适配器不会重定向到 Red Hat Single Sign-On。例如,如果您已向应用程序 mysecuredapp
进行了身份验证,打开 http://myappserver/mysecuredapp?prompt=login 不会自动重定向到 Red Hat Single Sign-On 登录页面。以后可能会更改此行为。
2.1.14. 客户端身份验证
当机密 OIDC 客户端需要发送后台请求(例如,交换令牌的代码,或刷新令牌)时,它需要与红帽单点登录服务器进行身份验证。默认情况下,可以通过三种方式验证客户端:客户端 ID 和客户端 secret,使用签名 JWT 进行客户端身份验证,或者使用客户端 secret 使用签名 JWT 进行客户端身份验证。
2.1.14.1. 客户端 ID 和客户端 Secret
这是 OAuth2 规范中描述的传统方法。客户端有一个 secret,需要知道适配器(应用程序)和 Red Hat Single Sign-On 服务器。您可以在 Red Hat Single Sign-On Admin Console 中为特定客户端生成 secret,然后将此 secret 粘贴到应用程序端的 keycloak.json
文件中:
"credentials": { "secret": "19666a4f-32dd-4049-b082-684c74115f28" }
2.1.14.2. 使用签名 JWT 进行客户端身份验证
这基于 RFC7523 规格。它以以下方式工作:
-
客户端必须具有私钥和证书。对于 Red Hat Single Sign-On,可以通过传统的
密钥存储文件
提供,该文件可在客户端应用的类路径或文件系统中某一位置提供。 - 客户端应用程序启动后,它允许使用 URL(如 http://myhost.com/myapp/k_jwks)以 JWKS 格式下载其公钥,假设 http://myhost.com/myapp 是客户端应用程序的基本 URL。红帽单点登录可以使用此 URL(请参阅以下)。
-
在身份验证过程中,客户端会生成 JWT 令牌,并使用其私钥对其进行签名,并将其发送到特定的后端请求(如
client_assertion
参数中的代码到令牌请求)。 Red Hat Single Sign-On 必须具有客户端的公钥或证书,以便它能够在 JWT 上验证签名。在 Red Hat Single Sign-On 中,您需要为您的客户端配置客户端凭证。首先,您需要在管理控制台中的
凭据
中选择Signed JWT
作为对客户端进行身份验证的方法。然后,您可以选择在键
选项卡中选择:-
配置红帽单点登录可下载客户端公钥的 JWKS URL。这可以是一个 URL,如 http://myhost.com/myapp/k_jwks(请参阅上面的详细信息)。这个选项是最灵活的,因为客户端可以随时轮转其密钥,然后在需要时始终下载新密钥,而无需更改配置。更准确地,红帽单点登录会在看到由未知
kid
(密钥 ID)签名的令牌时下载新密钥。 - 以 PEM 格式、采用 JWK 格式或从密钥存储上传客户端的公钥或证书。使用此选项时,公钥是硬编码的,在客户端生成新密钥对时必须更改。如果没有可用的红帽单点登录管理控制台,您也可以从红帽单点登录管理控制台生成自己的密钥存储。有关如何设置红帽单点登录管理控制台的详情,请查看 服务器管理指南。
-
配置红帽单点登录可下载客户端公钥的 JWKS URL。这可以是一个 URL,如 http://myhost.com/myapp/k_jwks(请参阅上面的详细信息)。这个选项是最灵活的,因为客户端可以随时轮转其密钥,然后在需要时始终下载新密钥,而无需更改配置。更准确地,红帽单点登录会在看到由未知
要在适配器中设置,您需要在 keycloak.json
文件中具有类似如下的内容:
"credentials": { "jwt": { "client-keystore-file": "classpath:keystore-client.jks", "client-keystore-type": "JKS", "client-keystore-password": "storepass", "client-key-password": "keypass", "client-key-alias": "clientkey", "algorithm": "RS256", "token-expiration": 10 } }
使用这个配置,密钥存储文件 keystore-client.jks
必须在您的 WAR 中的 classpath 上可用。如果不使用前缀 classpath:
您可以指向运行客户端应用程序的文件系统中的任何文件。
algorithm
字段指定用于签名 JWT 的算法,默认为 RS256
。此字段应当与密钥对同步。例如,RS256
算法需要 RSA 密钥对,而 ES256
算法需要 EC 密钥对。如需更多信息,请参阅 Cryptographic Algorithms 用于数字签名和 MAC。
2.1.15. 多租户
在我们的环境中,多元意味着可以使用多个红帽单点登录域保护单一目标应用程序(WAR)。域可以位于同一红帽单点登录实例或不同的实例上。
实际上,这意味着应用程序需要有多个 keycloak.json
适配器配置文件。
您可以有多个 WAR 实例,它们不同的适配器配置文件部署到不同的上下文路径。但是,这可能很不便,您可能还希望根据上下文路径以外的其他内容选择域。
Red Hat Single Sign-On 使可以有一个自定义配置解析器,以便您可以选择每个请求的适配器配置。
要实现这一点,首先需要创建 org.keycloak.adapters.KeycloakConfigResolver
的实现。例如:
package example; import org.keycloak.adapters.KeycloakConfigResolver; import org.keycloak.adapters.KeycloakDeployment; import org.keycloak.adapters.KeycloakDeploymentBuilder; public class PathBasedKeycloakConfigResolver implements KeycloakConfigResolver { @Override public KeycloakDeployment resolve(OIDCHttpFacade.Request request) { if (path.startsWith("alternative")) { KeycloakDeployment deployment = cache.get(realm); if (null == deployment) { InputStream is = getClass().getResourceAsStream("/tenant1-keycloak.json"); return KeycloakDeploymentBuilder.build(is); } } else { InputStream is = getClass().getResourceAsStream("/default-keycloak.json"); return KeycloakDeploymentBuilder.build(is); } } }
您还需要配置用于 web.xml
中的 keycloak.config.resolver
上下文-param 的 KeycloakConfigResolver
实现:
<web-app> ... <context-param> <param-name>keycloak.config.resolver</param-name> <param-value>example.PathBasedKeycloakConfigResolver</param-value> </context-param> </web-app>
2.1.16. 应用程序集群
本章与支持部署到 JBoss EAP 的集群应用程序相关。
根据您的应用程序是可用的一些选项:
- 无状态或有状态
- 可分发(复制的 http 会话)或不可分发的
- 依赖负载均衡器提供的粘性会话
- 托管在与 Red Hat Single Sign-On 相同的域中
处理集群的过程就像常规的应用程序一样简单。主要的原因是浏览器和服务器端应用程序向红帽单点登录发送请求,因此不像在您的负载均衡器上启用粘性会话那样简单。
2.1.16.1. 无状态令牌存储
默认情况下,Red Hat Single Sign-On 保护的 Web 应用程序使用 HTTP 会话来存储安全上下文。这意味着您必须启用粘性会话或复制 HTTP 会话。
作为在 HTTP 会话中存储安全上下文的替代方法,可将适配器配置为将其存储在 cookie 中。如果您要使应用程序无状态,或者您不想将安全上下文存储在 HTTP 会话中,这很有用。
要使用 Cookie 存储来保存安全上下文,请编辑应用程序 WEB-INF/keycloak.json
并添加:
"token-store": "cookie"
token-store
的默认值为 session
,它将安全上下文存储在 HTTP 会话中。
使用 cookie 存储的一个限制是,整个安全性上下文将针对每个 HTTP 请求在 cookie 中传递。这可能会影响性能。
另一个较小的限制是,对单点登录的支持有限。如果您从应用程序本身发起 servlet logout(HttpServletRequest.logout),它没有问题,因为适配器将删除 KEYCLOAK_ADAPTER_STATE cookie。但是,从不同应用程序初始化的频道注销不会由 Red Hat Single Sign-On 传播到使用 cookie 存储的应用程序。因此,建议对访问令牌超时使用简短值(例如 1 分钟)。
有些负载均衡器不允许配置粘性会话 Cookie 名称或内容,如 Amazon ALB。对于这些,建议将 shouldAttachRoute
选项设置为 false
。
2.1.16.2. 相对 URI 优化
在部署情况下,Red Hat Single Sign-On 和应用程序托管在同一域中(通过反向代理或负载均衡器),它可以方便地在客户端配置中使用相对 URI 选项。
对于相对 URI,则根据用于访问 Red Hat Single Sign-On 的 URL 解析 URI。
例如,如果您的应用程序的 URL 是 https://acme.org/myapp
,Red Hat Single Sign-On 的 URL 为 https://acme.org/auth
,您可以使用 redirect-uri /myapp
而不是 https://acme.org/myapp
。
2.1.16.3. 管理 URL 配置
可以在红帽单点登录管理控制台中配置特定客户端的管理 URL。红帽单点登录服务器用于向应用程序发送后端请求以获取各种任务,如注销用户或推送撤销策略。
例如,后端频道注销的工作方式为:
- 用户从一个应用程序发送注销请求
- 应用程序向 Red Hat Single Sign-On 发送注销请求
- Red Hat Single Sign-On 服务器使用户会话无效
- 然后,Red Hat Single Sign-On 服务器会向应用程序发送一个与会话关联的 admin url 的后方请求
- 当应用程序收到注销请求时,它会使对应的 HTTP 会话无效
如果 admin URL 包含 ${application.session.host}
,它将被替换为与 HTTP 会话关联的节点的 URL。
2.1.16.4. 注册应用程序节点
上一节中介绍了 Red Hat Single Sign-On 如何发送注销请求到与特定 HTTP 会话关联的节点。然而,在某些情况下,管理员可能希望将管理任务传播到所有注册的集群节点,而不只是其中之一。例如,在策略到应用程序之前将新版不推送到应用程序,或从应用程序注销所有用户。
在这种情况下,Red Hat Single Sign-On 需要了解所有应用程序集群节点,因此可以将事件发送到所有应用程序。要做到这一点,我们支持自动发现机制:
- 当新的应用程序节点加入集群时,它会向 Red Hat Single Sign-On 服务器发送注册请求
- 根据配置的定期间隔,请求可能会与 Red Hat Single Sign-On 重新输入
- 如果 Red Hat Single Sign-On 服务器没有在指定超时内收到重新注册请求,那么它会自动取消注册特定节点
- 当节点发送未注册或应用程序取消部署时,节点也会在 Red Hat Single Sign-On 中取消注册。如果没有调用非部署监听程序,这可能无法正常工作,这会导致自动取消注册
默认情况下,发送启动注册和定期重新注册功能会被禁用,因为它只是一些集群应用程序所需的。
要启用功能,为您的应用程序编辑 WEB-INF/keycloak.json
文件并添加:
"register-node-at-startup": true, "register-node-period": 600,
这意味着,适配器会在启动时发送注册请求,并每 10 分钟重新注册一次。
在 Red Hat Single Sign-On Admin Console 中,您可以指定最大节点 重新注册 超时(应该大于适配器配置中注册节点)。您还可以通过 Admin Console 手动添加和删除集群节点,如果您不想依赖自动注册功能,或者想要删除过时的应用程序节点(如果不使用自动取消注册功能),这会很有用。
2.1.16.5. 每个请求中的刷新令牌
默认情况下,应用程序适配器仅在访问令牌过期时刷新访问令牌。但是,您也可以将适配器配置为在每个请求中刷新令牌。这可能会对性能产生影响,因为您的应用程序将向红帽单点登录服务器发送更多请求。
要启用功能,为您的应用程序编辑 WEB-INF/keycloak.json
文件并添加:
"always-refresh-token": true
这可能会对性能有显著影响。只有您无法依赖 backchannel 消息传播注销而不是在策略前启用此功能。需要考虑的另一个因素是,默认情况下访问令牌具有较短的到期时间,因此即使注销不会传播令牌在注销后才会过期。