第 3 章 使用 SAML 保护应用程序和服务
本节论述了如何使用 Red Hat Single Sign-On 客户端适配器或通用 SAML 供应商库来保护应用程序和服务。
3.1. Java 适配器 复制链接链接已复制到粘贴板!
Red Hat Single Sign-On 带有 Java 应用程序的不同适配器范围。选择正确的适配器取决于目标平台。
3.1.1. 常规适配器配置 复制链接链接已复制到粘贴板!
Red Hat Single Sign-On 支持的每个 SAML 客户端适配器均可通过简单的 XML 文本文件配置。这种情况可能如下所示:
其中一些配置切换可能特定于适配器,一些配置交换机在所有适配器中都很常见。对于 Java 适配器,您可以使用 ${…} parture 作为系统属性替换。例如: ${jboss.server.config.dir}
3.1.1.1. SP 元素 复制链接链接已复制到粘贴板!
以下是 SP 元素属性的解释:
- entityID
- 这是此客户端的标识符。IdP 需要这个值来确定客户端与之通信的人员。此设置是 REQUIRED。
- sslPolicy
-
这是适配器要强制执行的 SSL 策略。有效值为:
所有、EXTERNAL和NONE。对于ALL,所有请求都必须通过 HTTPS。对于EXTERNAL,只有非专用 IP 地址必须通过 HTTPS 进行线路。对于NONE,不需要通过 HTTPS 访问请求。此设置是 OPTIONAL。默认值为EXTERNAL。 - nameIDPolicyFormat
-
SAML 客户端可以请求特定的 NameID 主体格式。如果您希望特定格式,请填写此值。它必须是标准的 SAML 格式标识符:urn
:oasis:names:tc:SAML:2.0:nameid-format:transient.此设置是 OPTIONAL。默认情况下,请求没有特殊格式。 - forceAuthentication
-
SAML 客户端可以请求重新验证用户,即使他们已在 IdP 登录时。把它设置为
true来启用。此设置是 OPTIONAL。默认值为false。 - isPassive
-
SAML 客户端可能会要求用户进行身份验证,即使他们没有在 IdP 登录时也如此。如果需要这样做,则将其设置为
true。不要与forceAuthentication一起使用,因为它们相反。此设置是 OPTIONAL。默认值为false。 - turnOffChangeSessionIdOnLogin
-
在某些平台上成功登录时,会话 ID 被默认更改,以插入安全攻击向量。将此更改为
true以禁用此功能。建议您不要关闭它。默认值为false。 - autodetectBearerOnly
-
如果您的应用程序同时充当 Web 应用程序和 Web 服务(如 SOAP 或 REST),则此项应设为 true。它允许您将 Web 应用的未经身份验证的用户重定向到 Red Hat Single Sign-On 登录页面,但向未经身份验证的 SOAP 或 REST 客户端发送 HTTP
401状态代码,因为它们不知道到登录页面的重定向。红帽单点登录根据典型的标头(如X-Requested-With、SOAPAction或Accept)自动探测 SOAP 或 REST 客户端。默认值为 false。 - logoutPage
-
这会将页面设置为在注销后显示。如果页面是一个完整的 URL,如
http://web.example.com/logout.html,则在使用 HTTP302状态代码注销至该页面后,用户会被重定向到该页面。如果指定了没有方案部分的链接,如/logout.jsp,则该页面会在注销后显示,无论它是否根据 web.xml 中的security-constraint声明显示在受保护区域中,并且页面会相对于部署上下文 root 解析。 - keepDOMAssertion
-
此属性应设为 true,以便适配器将声明的 DOM 表示存储在与请求关联的 SamlPrincipal 的
SamlPrincipal中。可以使用主体中的getAsertionDocument 来检索断言文档。这在重新显示签名的断言时特别有用。返回的文档是生成解析 Red Hat Single Sign-On 服务器收到的 SAML 响应的文件。此设置是 OPTIONAL,其默认值为 false (文件没有在主体内保存)。
3.1.1.2. 服务提供商密钥和关键元素 复制链接链接已复制到粘贴板!
如果 IdP 需要客户端应用程序(或 SP)为其所有请求签名,或者,如果 IdP 会加密断言,则必须定义用于执行此操作的密钥。对于客户端签名文档,您必须定义用于签署文档的私钥和公钥或证书。为了进行加密,您只需要定义用于解密的私钥。
可以通过两种方式描述您的密钥。它们可存储在 Java KeyStore 中,或者您可以使用 PEM 格式直接将密钥复制到 keycloak-saml.xml 中。
<Keys>
<Key signing="true" >
...
</Key>
</Keys>
<Keys>
<Key signing="true" >
...
</Key>
</Keys>
Key 元素有两个可选属性 signing 和 encryption。当设置为 true 时,它们告诉适配器将用于什么键。如果这两个属性都设为 true,则密钥将同时用于签名文档和解密加密的断言。您必须至少将其中一个属性设置为 true。
3.1.1.2.1. keystore 元素 复制链接链接已复制到粘贴板!
在 Key 元素中,您可以从 Java 密钥存储加载您的密钥和证书。这在 KeyStore 元素中声明。
以下是使用 KeyStore 元素定义的 XML 配置属性。
- file
- 密钥存储的文件路径。此选项是 OPTIONAL。必须设置 file 或 resource 属性。
- resource
- WAR 资源路径到 KeyStore。这是对 ServletContext.getResourceAsStream()方法调用的路径。此选项是 OPTIONAL。必须设置 file 或 resource 属性。
- password
- KeyStore 的密码。此选项为 REQUIRED。
如果要定义 SP 用于签名的密钥,还必须在 Java KeyStore 中指定您的私钥和证书的引用。上例中的 PrivateKey 和 Certificate 元素定义了一个 alias,指向密钥存储内密钥或证书。密钥存储需要额外密码才能访问私钥。在 PrivateKey 元素中,您必须在 password 属性中定义此密码。
3.1.1.2.2. 密钥 PEMS 复制链接链接已复制到粘贴板!
在 Key 元素中,您可以使用子元素( PrivateKeyPem、PublicKeyPem 和 CertificatePem )来直接声明您的密钥和证书。这些元素中包含的值必须符合 PEM 密钥格式。如果您使用 openssl 或类似的命令行工具生成密钥,通常会使用这个选项。
3.1.1.3. SP PrincipalNameMapping 元素 复制链接链接已复制到粘贴板!
这个元素是可选的。创建您从 HttpServletRequest.getUserPrincipal() 等方法获取的 Java Principal 对象时,您可以定义 Principal.getName() 方法返回的名称。
policy 属性定义用于填充该值的策略。此属性的可能值有:
- FROM_NAME_ID
- 此策略仅使用任何 SAML 主题值。这是默认设置
- FROM_ATTRIBUTE
-
这将从服务器收到的 SAML 断言中声明的属性中拉取值。您将需要指定要在
attributeXML 属性中使用的 SAML 断言属性的名称。
3.1.1.4. RoleIdentifiers 元素 复制链接链接已复制到粘贴板!
RoleIdentifiers 元素定义了从用户接收的断言中的 SAML 属性,用作用户的 Jakarta EE 安全上下文中的角色标识符。
<RoleIdentifiers>
<Attribute name="Role"/>
<Attribute name="member"/>
<Attribute name="memberOf"/>
</RoleIdentifiers>
<RoleIdentifiers>
<Attribute name="Role"/>
<Attribute name="member"/>
<Attribute name="memberOf"/>
</RoleIdentifiers>
默认情况下,Role 属性值转换为 Jakarta EE 角色。有些 IdP 使用 member 或 memberOf 属性断言角色。您可以定义一个或多个 Attribute 元素,以指定哪些 SAML 属性必须转换为角色。
3.1.1.5. RoleMappingsProvider 元素 复制链接链接已复制到粘贴板!
RoleMappingsProvider 是一个可选元素,它允许规范 org.keycloak.adapters.saml.RoleMappingsProvider SPI 实现,供 SAML 适配器使用。
当 Red Hat Single Sign-On 用作 IDP 时,可以使用角色映射程序中的构建来映射任何角色,然后才能将它们添加到 SAML 断言。但是,SAML 适配器可用于发送 SAML 请求到第三方 IDP,在这种情况下,可能需要将断言中提取的角色映射到 SP 需要的不同角色。RoleMappingsProvider SPI 允许配置可用来执行必要映射的可插拔角色映射程序。
供应商的配置如下所示:
id 属性标识要使用哪个已安装的提供程序。Property 子元素可以多次使用来为提供程序指定配置属性。
3.1.1.5.1. 基于属性的角色映射提供程序 复制链接链接已复制到粘贴板!
Red Hat Single Sign-On 包括一个 RoleMappingsProvider 实现,它使用 properties 文件来执行角色映射。此提供程序由 id 属性-role-mapper 识别,并由 org.keycloak.adapters.saml.PropertiesBasedRoleMapper 类实施。
此提供程序依赖于两个配置属性,它们可用于指定要使用的 属性 文件的位置。首先,它会检查 properties.file.location 是否被设置,使用配置的值来查找文件系统中的 properties 文件。如果配置文件不位于,则提供程序会抛出 RuntimeException。以下片段演示了使用 properties.file.configuration 选项从文件系统中的 /opt/mappers/ 目录中加载 roles.properties 文件的供应商示例:
<RoleMappingsProvider id="properties-based-role-mapper">
<Property name="properties.file.location" value="/opt/mappers/roles.properties"/>
</RoleMappingsProvider>
<RoleMappingsProvider id="properties-based-role-mapper">
<Property name="properties.file.location" value="/opt/mappers/roles.properties"/>
</RoleMappingsProvider>
如果没有设置 properties.file.location,则供应商会检查 properties.resource.location 属性,使用配置的值来从 WAR 资源中加载 properties 文件。如果该配置属性也不存在,则供应商将默认尝试从 /WEB-INF/role-mappings.properties 加载该文件。无法从资源加载文件将导致提供程序引发 RuntimeException。以下片段演示了使用 properties.resource.location 从应用程序的 /WEB-INF/conf/ 目录中加载 roles.properties 文件的供应商示例:
<RoleMappingsProvider id="properties-based-role-mapper">
<Property name="properties.resource.location" value="/WEB-INF/conf/roles.properties"/>
</RoleMappingsProvider>
<RoleMappingsProvider id="properties-based-role-mapper">
<Property name="properties.resource.location" value="/WEB-INF/conf/roles.properties"/>
</RoleMappingsProvider>
属性 文件可以包含角色和主体作为键,以及以逗号分隔的零个角色列表作为值。调用后,如果存在映射,实施将迭代从断言和检查中提取的角色集合。如果角色映射到空角色,它将被丢弃。如果它映射到一个或多个不同的角色,则会在结果集中设置这些角色。如果没有为角色找到映射,则会包含在结果集中。
处理角色后,实施将检查从断言中提取的主体是否包含一个条目 属性文件。如果存在主体的映射,则所有作为值列出的角色都会添加到结果集中。这允许将额外角色分配给主体。
例如,假设供应商已经使用以下属性文件进行配置:
roleA=roleX,roleY roleB= kc_user=roleZ
roleA=roleX,roleY
roleB=
kc_user=roleZ
如果主体 kc_user 从角色 roleA、roleB 和 roleC 中提取,则分配给主体的最终角色集将是 roleC、roleX、roleY 和 roleZ,因为 roleA 被映射到 roleX 和 roleY。 roleB 已映射到空角色 - 因此被丢弃,roleC 被用作,最后会添加额外的角色到 kc_user 主体(roleZ)。
注: 要在角色名称中使用空格进行映射,使用 unicode 替换空间。例如,传入"角色 A"将如下所示:
role\u0020A=roleX,roleY
role\u0020A=roleX,roleY
3.1.1.5.2. 添加您自己的角色映射供应商 复制链接链接已复制到粘贴板!
要添加自定义角色映射提供程序,只需实施 org.keycloak.adapters.saml.RoleMappingsProvider SPI。如需了解更多详细信息,请参阅 服务器开发者指南中的 SAML 角色映射 SPI 部分。
3.1.1.6. IDP Element 复制链接链接已复制到粘贴板!
IDP 元素中的所有内容描述了 SP 通信身份提供程序(身份验证服务器)的设置。
以下是您可以在 IDP 元素声明中指定的属性配置选项。
- entityID
- 这是 IDP 的签发者 ID。此设置是 REQUIRED。
- signaturesRequired
-
如果设置为
true,则客户端适配器都将为其发送到 IDP 的每个文档进行签名。另外,客户端会期望 IDP 将会对发送给它的所有文档进行签名。此切换为所有请求和响应类型设置默认值,但稍后您会看到您对此有非常精细的控制。此设置是 选项, 并且默认为false。 - signatureAlgorithm
-
这是 IDP 期望签名的文档使用的签名算法。允许的值有:
RSA_SHA1、RSA_SHA256、RSA_SHA512和DSA_SHA1。此设置是 OPTIONAL,默认为RSA_SHA256。 - signatureCanonicalizationMethod
-
这是 IDP 预期签名的文档要使用的签名规范方法。此设置是 OPTIONAL。默认值为
http://www.w3.org/2001/10/xml-exc-c14n#,它应该适用于大多数 IDP。 - metadataUrl
- 用于检索 IDP 元数据的 URL,目前它只用来定期获取签名和加密密钥,允许循环在 IDP 上不手动更改这些密钥。
3.1.1.7. IDP AllowedClockSkew 子元素 复制链接链接已复制到粘贴板!
AllowedClockSkew 可选子元素定义 IDP 和 SP 之间的允许时钟偏移。默认值为 0。
<AllowedClockSkew unit="MILLISECONDS">3500</AllowedClockSkew>
<AllowedClockSkew unit="MILLISECONDS">3500</AllowedClockSkew>
- unit
-
可以定义附加到此元素值的时间范围。允许的值是 MICROSECONDS、MILLISECONDS、MINUTES、NANOSECONDS 和 SECONDS。这是 选项。默认值为
SECONDS。
3.1.1.8. IDP SingleSignOnService 子元素 复制链接链接已复制到粘贴板!
SingleSignOnService 子元素定义 IDP 的登录 SAML 端点。客户端适配器会在需要登录时通过此元素中的设置将请求发送到 IDP。
<SingleSignOnService signRequest="true"
validateResponseSignature="true"
requestBinding="post"
bindingUrl="url"/>
<SingleSignOnService signRequest="true"
validateResponseSignature="true"
requestBinding="post"
bindingUrl="url"/>
以下是您可以在此元素上定义的配置属性:
- signRequest
-
客户端签名身份验证是否请求?此设置是 OPTIONAL。默认为 IDP
签名Required元素值。 - validateResponseSignature
-
客户端是否希望 IDP 签署从uhtn 请求发回的断言响应文档?此设置是 OPTIONAL。默认为 IDP
签名Required元素值。 - requestBinding
-
这是用于与 IDP 通信的 SAML 绑定类型。此设置是 OPTIONAL。默认值为
POST,但您也可以将其设置为REDIRECT。 - responseBinding
-
SAML 允许客户端请求使用什么绑定类型。这个值可以是
POST或REDIRECT。此设置是 OPTIONAL。默认值是客户端不会为响应请求特定绑定类型。 - assertionConsumerServiceUrl
-
断言使用者服务(ACS)的 URL,IDP 登录服务应向其中发送响应。此设置是 OPTIONAL。默认情况下,不设置它,它依赖于 IdP 中的配置。设置后,它必须以
/saml结尾,例如http://sp.domain.com/my/endpoint/for/saml。此属性的值以 SAMLAuthnRequest消息的AssertionConsumerServiceURL属性中发送。此属性通常由responseBinding属性使用。 - bindingUrl
- 这是客户端将向其发送请求的 IDP 登录服务的 URL。此设置是 REQUIRED。
3.1.1.9. IDP SingleLogoutService 子元素 复制链接链接已复制到粘贴板!
SingleLogoutService 子元素定义 IDP 的注销 SAML 端点。在希望注销时,客户端适配器将通过此元素中的设置将请求发送到 IDP。
- signRequest
-
客户端注销请求是否应该进入 IDP?此设置是 OPTIONAL。默认为 IDP
签名Required元素值。 - signResponse
-
客户端注销响应是否应该发送到 IDP 请求?此设置是 OPTIONAL。默认为 IDP
签名Required元素值。 - validateRequestSignature
-
客户端是否应该从 IDP 中签署注销请求文档?此设置是 OPTIONAL。默认为 IDP
签名Required元素值。 - validateResponseSignature
-
客户端是否应该从 IDP 中签署注销响应文档?此设置是 OPTIONAL。默认为 IDP
签名Required元素值。 - requestBinding
-
这是用于向 IDP 通信 SAML 请求的 SAML 绑定类型。此设置是 OPTIONAL。默认值为
POST,但您也可以将其设置为 REDIRECT。 - responseBinding
-
这是用于向 IDP 通信 SAML 响应的 SAML 绑定类型。这个值可以是
POST或REDIRECT。此设置是 OPTIONAL。默认值为POST,但您也可以将其设置为REDIRECT。 - postBindingUrl
-
这是使用 POST 绑定时 IDP 的注销服务的 URL。如果使用
POST绑定,则此设置为 REQUIRED。 - redirectBindingUrl
- 这是使用 REDIRECT 绑定时 IDP 注销服务的 URL。如果使用 REDIRECT 绑定,则此设置为 REQUIRED。
3.1.1.10. IDP Keys 子元素 复制链接链接已复制到粘贴板!
IDP 的密钥子元素仅用于定义用于验证由 IDP 签署的证书或公钥。它定义方式与 SP 的 Keys 元素 相同。但是,您只需要定义一个证书或公钥引用。请注意,如果 Red Hat Single Sign-On 服务器和 adapter 分别意识到 IDP 和 SP,则不需要指定签名验证的密钥,请参阅以下。
可将 SP 配置为从已发布的证书中获取 IDP 签名验证的公钥,只要 Red Hat Single Sign-On 均实施 SP 和 IDP。这可以通过删除 Keys 子元素中的所有签名验证密钥声明来实现。如果 Keys 子元素保持为空,则可以完全省略它。然后,SP 从 SAML 描述符自动获取密钥,该位置派生自 IDP SingleSignOnService 子元素 中指定的 SAML 端点 URL。用于 SAML 描述符检索的 HTTP 客户端的设置通常需要额外的配置,但它可以在 IDP HttpClient 子元素 中配置。
也可以指定多个用于签名验证的密钥。这可以通过在 Keys 子元素内声明多个 Key 元素,并将 signing 属性设置为 true。例如,当 IDP 签名密钥被轮转时,这很有用:新的 SAML 协议消息和断言通常是一个转换周期,但仍应该接受之前密钥签名的断言。
无法将 Red Hat Single Sign-On 配置为自动获取签名验证的密钥并定义额外的静态签名验证密钥。
3.1.1.11. IDP HttpClient 子元素 复制链接链接已复制到粘贴板!
HttpClient 可选子元素定义了 HTTP 客户端的属性,用于在 启用时 通过 IDP 的 SAML 描述符自动获取包含 IDP 签名验证的公钥的 HTTP 客户端的属性。
- connectionPoolSize
-
此配置选项定义应池与红帽单点登录服务器的连接数量。这是 选项。默认值为
10。 - disableTrustManager
-
如果 Red Hat Single Sign-On 服务器需要 HTTPS,且这个配置选项被设置为
true,则不需要指定信任存储。此设置应只在开发期间使用,永远不会 在生产环境中使用,因为它将禁用 SSL 证书的验证。这是 选项。默认值为false。 - allowAnyHostname
-
如果 Red Hat Single Sign-On 服务器需要 HTTPS,且该配置选项被设置为
true,则红帽单点登录服务器的证书通过信任存储进行验证,但不会执行主机名验证。此设置只应在开发期间使用,永远不会 在生产环境中使用,因为它将部分禁用 SSL 证书的验证。这集在测试环境中可能很有用。这是 选项。默认值为false。 - truststore
-
值是信任存储文件的文件路径。如果您使用
classpath:前缀,则信任存储将从部署的 classpath 获取。用于向 Red Hat Single Sign-On 服务器的传出 HTTPS 通信。进行 HTTPS 请求的客户端需要一种验证它们要通信的服务器主机的方法。这就是信任者的作用。该密钥存储包含一个或多个可信主机证书或证书颁发机构。您可以通过提取红帽单点登录服务器的 SSL 密钥存储的公共证书来创建此信任存储。这是 REQUIRED,除非disableTrustManager为true。 - truststorePassword
-
truststore 的密码。如果设置了
truststore且信任存储需要密码,则这是 REQUIRED。 - clientKeystore
- 这是密钥存储文件的文件路径。当适配器向 Red Hat Single Sign-On 服务器发出 HTTPS 请求时,此密钥存储包含双向 SSL 的客户端证书。这是 选项。
- clientKeystorePassword
-
客户端密钥存储的密码,以及客户端的密钥。如果设置了
clientKeystore,则这是 REQUIRED。 - proxyUrl
- 用于 HTTP 连接的 HTTP 代理服务器的 URL。这是 选项。
- socketTimeout
-
在建立连接(以毫秒为单位)后,套接字等待数据的超时。在两个数据包之间不活跃的最大时间。超时值为零将解释为无限超时。负值代表为未定义(如果适用,系统默认值)。默认值为
-1。这是 选项。 - connectionTimeout
-
与远程主机建立连接的超时(以毫秒为单位)。超时值为零将解释为无限超时。负值代表为未定义(如果适用,系统默认值)。默认值为
-1。这是 选项。 - connectionTtl
-
以毫秒为单位连接客户端到实时的连接时间。小于或等于零的值被解释为无限值。默认值为
-1。这是 选项。
3.1.2. JBoss EAP 适配器 复制链接链接已复制到粘贴板!
为了保护 JBoss EAP 上部署的 WAR 应用安全,您必须安装并配置 Red Hat Single Sign-On SAML Adapter subsystem。
然后,您可以在 WAR 中提供 keycloak 配置 /WEB-INF/keycloak-saml.xml 文件,并将 auth-method 更改为 web.xml 中的 KEYCLOAK-SAML。
您可以使用 ZIP 文件或 RPM 安装适配器。
3.1.3. 从 ZIP 文件安装适配器 复制链接链接已复制到粘贴板!
每个适配器是在 Red Hat Single Sign-On 下载站点单独下载。
流程
从 Downloads 网站安装适用于您的应用程序服务器的适配器。
在 JBoss EAP 7.x 上安装:
cd $EAP_HOME unzip rh-sso-saml-eap7-adapter.zip
$ cd $EAP_HOME $ unzip rh-sso-saml-eap7-adapter.zipCopy to Clipboard Copied! Toggle word wrap Toggle overflow 在 JBoss EAP 6.x 上安装:
cd $EAP_HOME unzip rh-sso-saml-eap6-adapter.zip
$ cd $EAP_HOME $ unzip rh-sso-saml-eap6-adapter.zipCopy to Clipboard Copied! Toggle word wrap Toggle overflow 这些 ZIP 文件会创建特定于 JBoss EAP 分发中的 JBoss EAP SAML 适配器的新 JBoss 模块。
使用 CLI 脚本在应用服务器的服务器配置中启用红帽单点登录 SAML subsystem:
domain.xml或standalone.xml。启动服务器并运行适用于您的应用服务器的脚本。
对 JBoss EAP 7.1 或更新版本使用此命令
cd $JBOSS_HOME ./bin/jboss-cli.sh -c --file=bin/adapter-elytron-install-saml.cli
$ cd $JBOSS_HOME $ ./bin/jboss-cli.sh -c --file=bin/adapter-elytron-install-saml.cliCopy to Clipboard Copied! Toggle word wrap Toggle overflow 注意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 7.0 和 EAP 6.4 使用此命令
cd $JBOSS_HOME ./bin/jboss-cli.sh -c --file=bin/adapter-install-saml.cli
$ cd $JBOSS_HOME $ ./bin/jboss-cli.sh -c --file=bin/adapter-install-saml.cliCopy to Clipboard Copied! Toggle word wrap Toggle overflow 注意也可以在 JBoss EAP 7.1 或更新版本中使用旧的非tron 适配器,这意味着您可以在这些版本中使用
adapter-install-saml.cli。但是,我们建议您使用较新的 Elytron 适配器。该脚本将添加扩展、子系统以及可选的 security-domain,如下所述。
当您需要在受保护的 Web 层中创建的安全上下文被传播到您正调用的 EJB(其它 EE 组件)时,其中的 keycloak 安全域应当与 EJBs 和其他组件一起使用。否则此配置是可选的。
安全上下文自动传播到 EJB 层。
3.1.3.1. JBoss SSO 复制链接链接已复制到粘贴板!
JBoss EAP 内置了对部署到同一 JBoss EAP 实例的 Web 应用程序的单点登录支持。使用 Red Hat Single Sign-On 时不应该启用此功能。
3.1.3.2. 为 JSESSIONID Cookie 设置 SameSite 值 复制链接链接已复制到粘贴板!
浏览器计划将 Cookie 的 SameSite 属性的默认值设置为 Lax。此设置表示,仅当请求源自于同一域中时,cookies 才会发送到应用程序。这个行为可能会影响 SAML POST 绑定,这可能会变为无法正常工作。要保留 SAML 适配器的完整功能,我们建议将容器创建的 JSESSIONID cookie 的 SameSite 值设置为 None。不这样做可能会导致对每个请求重置容器的会话。
要避免将 SameSite 属性设置为 None,请考虑切换到 REDIRECT 绑定(如果可接受),或者使用这个临时解决方案的 OIDC 协议。
要将 Wildfly/EAP 中的 JSESSIONID cookie 的 SameSite 值设置为 None,请在应用程序的 WEB-INF 目录中添加 file undertow-handlers.conf。
samesite-cookie(mode=None, cookie-pattern=JSESSIONID)
samesite-cookie(mode=None, cookie-pattern=JSESSIONID)
对此配置的支持在 19.1.0 版本中的 Wildfly 中提供。
3.1.4. 从 RPM 安装 JBoss EAP 7 Adapter 复制链接链接已复制到粘贴板!
使用 Red Hat Enterprise Linux 7 时,术语频道被替换为术语仓库。这些说明中,仅使用术语库。
先决条件
您必须订阅 JBoss EAP 7 存储库,然后才能从 RPM 安装 EAP 7 适配器。
- 确定使用 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
$ sudo subscription-manager repos --enable=jb-eap-7-for-rhel-<RHEL_VERSION>-server-rpmsCopy to Clipboard Copied! Toggle word wrap Toggle overflow 对于 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
$ 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-rpmsCopy to Clipboard Copied! Toggle word wrap Toggle overflow
流程
根据您的 Red Hat Enterprise Linux 版本,为 SAML 安装 EAP 7 适配器。
在 Red Hat Linux 7 上安装:
sudo yum install eap7-keycloak-saml-adapter-sso7_6
$ sudo yum install eap7-keycloak-saml-adapter-sso7_6Copy to Clipboard Copied! Toggle word wrap Toggle overflow 在 Red Hat Enterprise Linux 8 中安装:
sudo dnf install eap7-keycloak-adapter-sso7_6
$ sudo dnf install eap7-keycloak-adapter-sso7_6Copy to Clipboard Copied! Toggle word wrap Toggle overflow 注意RPM 安装的默认 EAP_HOME 路径为 /opt/rh/eap7/root/usr/share/wildfly。
为 SAML 模块运行安装脚本:
$EAP_HOME/bin/jboss-cli.sh -c --file=$EAP_HOME/bin/adapter-install-saml.cli
$ $EAP_HOME/bin/jboss-cli.sh -c --file=$EAP_HOME/bin/adapter-install-saml.cliCopy to Clipboard Copied! Toggle word wrap Toggle overflow
您的安装已完成。
3.1.5. 从 RPM 安装 JBoss EAP 6 Adapter 复制链接链接已复制到粘贴板!
使用 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
$ sudo subscription-manager repos --enable=jb-eap-6-for-rhel-<RHEL_VERSION>-server-rpmsCopy to Clipboard Copied! Toggle word wrap Toggle overflow
流程
使用以下命令为 SAML 安装 EAP 6 适配器:
sudo yum install keycloak-saml-adapter-sso7_6-eap6
$ sudo yum install keycloak-saml-adapter-sso7_6-eap6Copy to Clipboard Copied! Toggle word wrap Toggle overflow 注意RPM 安装的默认 EAP_HOME 路径为 /opt/rh/eap6/root/usr/share/wildfly。
为 SAML 模块运行安装脚本:
$EAP_HOME/bin/jboss-cli.sh -c --file=$EAP_HOME/bin/adapter-install-saml.cli
$ $EAP_HOME/bin/jboss-cli.sh -c --file=$EAP_HOME/bin/adapter-install-saml.cliCopy to Clipboard Copied! Toggle word wrap Toggle overflow
您的安装已完成。
3.1.5.1. 保护 WAR 复制链接链接已复制到粘贴板!
这部分论述了如何通过在 WAR 软件包中添加配置和编辑文件来直接保护 WAR。
您首先在 WAR 的 WEB-INF 目录下创建一个 keycloak-saml.xml 适配器配置文件。常规 适配器配置部分描述了此配置文件的格式。
接下来,您必须在 web.xml 中将 auth-method 设置为 KEYCLOAK-SAML。您还必须使用标准 servlet 安全性为您的 URL 指定角色基础限制。以下是 web.xml 文件示例:
除 auth-method 设置外的所有标准 servlet 设置。
3.1.5.2. 使用红帽单点登录 SAML 子系统保护 WAR 复制链接链接已复制到粘贴板!
您不必打开 WAR 才能使用 Red Hat Single Sign-On 对其进行保护。另外,您还可以通过 Red Hat Single Sign-On SAML Adapter subsystem 对外部保护。虽然您不必将 KEYCLOAK-SAML 指定为 auth-method,但您仍必须在 web.xml 中定义 security-constraints。但是,您不必创建 WEB-INF/keycloak-saml.xml 文件。这个元数据会在服务器的 domain.xml 或 standalone.xml 子系统配置部分中的 XML 中定义。
secure-deployment name 属性标识您要保护的 WAR。其值是 web.xml 中定义的 module-name,并附加 .war。其余的配置使用与 General Adapter Config 中定义的 keycloak-saml.xml 配置相同的 XML 语法。
配置示例:
3.1.6. Java Servlet 过滤器适配器 复制链接链接已复制到粘贴板!
如果要将 SAML 与不属于 servlet 平台的适配器的 Java servlet 应用程序搭配使用,您可以选择使用 Red Hat Single Sign-On 拥有的 servlet 过滤器。这个适配器的工作方式与其它适配器不同。您仍然需要指定一个 /WEB-INF/keycloak-saml.xml 文件,如 General Adapter Config 部分中定义,但您不会在 web.xml 中定义安全限制。反之,您可以使用 Red Hat Single Sign-On servlet 过滤器适配器定义一个过滤器映射来保护您要保护的 url 模式。
Backchannel logout 与标准适配器不同。它而不是无效的 http 会话,而是将会话 ID 标记为已注销。不只是一个基于会话 ID 对 http 会话进行无效的方法。
当您有一个使用 SAML 过滤器的集群应用程序时,恢复通道注销将无法正常工作。
Red Hat Single Sign-On 过滤器具有与与其他适配器相同的配置参数,但您必须将它们定义为 filter init 参数,而不是上下文参数。
如果您有不同的安全和不安全的 url 模式,可以定义多个过滤器映射。
您必须有一个涵盖 /saml 的过滤器映射。此映射涵盖了所有服务器回调。
当将 SP 与 IdP 注册时,您必须将 http[s]://hostname/{context-root}/saml 注册为 Assert Consumer Service URL 和 Single Logout Service URL。
要使用此过滤器,请在 WAR poms 中包括这个 maven 工件:
<dependency> <groupId>org.keycloak</groupId> <artifactId>keycloak-saml-servlet-filter-adapter</artifactId> <version>18.0.18.redhat-00001</version> </dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-servlet-filter-adapter</artifactId>
<version>18.0.18.redhat-00001</version>
</dependency>
要使用 Multi Tenancy,keycloak.config.resolver 参数应作为过滤器参数传递。
3.1.7. 使用身份提供程序注册 复制链接链接已复制到粘贴板!
对于每个基于 servlet 的适配器,您注册了 assert 使用者服务 URL 的端点必须是 servlet 应用程序的基本 URL,附加有 /saml,即 https://example.com/contextPath/saml。
3.1.8. 退出 复制链接链接已复制到粘贴板!
您可以通过多种方式从 web 应用程序注销。对于 Jakarta EE servlet 容器,您可以调用 HttpServletRequest.logout()。对于任何其他浏览器应用程序,您可以将浏览器指向具有安全约束的 Web 应用的任何 url,并传递查询参数 GLO,例如 http://myapp?GLO=true。如果您通过浏览器具有 SSO 会话,这将注销。
3.1.8.1. 在集群环境中注销 复制链接链接已复制到粘贴板!
在内部,SAML 适配器会在 SAML 会话索引、主体名称(已知)和 HTTP 会话 ID 之间存储映射。此映射可以在 JBoss 应用服务器系列(WildFly 10/11、EAP 6/7)中维护,以供分布的应用程序使用。作为条件,需要在应用程序的 web.xml中使用 <distribut/> 标签分发 HTTP 会话(例如,应用程序标记为 <distriable /> 标签)。
要启用功能,请在 /WEB_INF/web.xml 文件中添加以下部分:
对于 EAP 7,WildFly 10/11:
<context-param>
<param-name>keycloak.sessionIdMapperUpdater.classes</param-name>
<param-value>org.keycloak.adapters.saml.wildfly.infinispan.InfinispanSessionCacheIdMapperUpdater</param-value>
</context-param>
<context-param>
<param-name>keycloak.sessionIdMapperUpdater.classes</param-name>
<param-value>org.keycloak.adapters.saml.wildfly.infinispan.InfinispanSessionCacheIdMapperUpdater</param-value>
</context-param>
对于 EAP 6:
<context-param>
<param-name>keycloak.sessionIdMapperUpdater.classes</param-name>
<param-value>org.keycloak.adapters.saml.jbossweb.infinispan.InfinispanSessionCacheIdMapperUpdater</param-value>
</context-param>
<context-param>
<param-name>keycloak.sessionIdMapperUpdater.classes</param-name>
<param-value>org.keycloak.adapters.saml.jbossweb.infinispan.InfinispanSessionCacheIdMapperUpdater</param-value>
</context-param>
如果部署的会话缓存命名为 deployment-cache,用于 SAML 映射的缓存将命名为 deployment-cache.ssoCache。缓存名称可以被 context 参数 keycloak.sessionIdMapperUpdater.infinispan.cacheName 覆盖。包含缓存的 cache 容器与包含部署会话缓存的 cache 容器相同,但可以被上下文参数 keycloak.sessionIdMapperUpdater.infinispan.containerName 覆盖。
默认情况下,SAML 映射缓存的配置将派生自会话缓存。可以手动覆盖与其它缓存相同的服务器的缓存配置部分。
目前,为了提供可靠的服务,建议将复制缓存用于 SAML 会话缓存。使用分布式缓存可能会导致 SAML 注销请求进入没有访问 SAML 会话索引到 HTTP 会话映射的节点,这会导致无法注销。
3.1.8.2. 退出跨站点情境 复制链接链接已复制到粘贴板!
跨站点方案仅适用于 WildFly 10 和更高版本,且 EAP 7 及更高版本。
处理跨越多个数据中心的会话需要特殊处理。考虑以下情境:
- 登录请求在数据中心 1 中处理。
- 管理员发出特定 SAML 会话的注销请求,请求进入数据中心 2。
数据中心 2 必须注销数据中心 1 中(以及共享 HTTP 会话的所有其他数据中心)存在的所有会话。
要涵盖这种情况,上述 SAML 会话缓存只需要在单个集群中复制,而是在所有数据中心复制,例如通过独立 Infinispan/JDG 服务器 :
- 缓存必须添加到独立的 Infinispan/JDG 服务器中。
- 必须将上一项中的缓存添加为对应 SAML 会话缓存的远程存储。
在部署期间找到了远程存储以在 SAML 会话缓存中存在后,则会监视更改,并相应地更新本地 SAML 会话缓存。
3.1.9. 获取断言属性 复制链接链接已复制到粘贴板!
成功 SAML 登录后,您的应用程序代码可能希望获取通过 SAML 断言传递的属性值。HttpServletRequest.getUserPrincipal() 返回 可进入 Red Hat Single Sign-On 特定类(名为 org.keycloak.adapters.saml.SamlPrincipal )的主体对象。此对象允许您查看原始的断言,以及便利函数来查找属性值。
3.1.10. 错误处理 复制链接链接已复制到粘贴板!
Red Hat Single Sign-On 对基于 servlet 的客户端适配器有一些错误处理功能。在身份验证中遇到错误时,客户端适配器将调用 HttpServletResponse.sendError()。您可以在 web.xml 文件中设置一个 错误页面 来处理错误。客户端适配器可能会抛出 400、401、403 和 500 错误。
<error-page>
<error-code>403</error-code>
<location>/ErrorHandler</location>
</error-page>
<error-page>
<error-code>403</error-code>
<location>/ErrorHandler</location>
</error-page>
客户端适配器还设置可检索的 HttpServletRequest 属性。属性名称是 org.keycloak.adapters.spi.AuthenticationError。Typecast this object to: org.keycloak.adapters.saml.SamlAuthenticationError.此类可以告诉您发生的情况。如果没有设置此属性,则适配器不负责错误代码。
3.1.11. 故障排除 复制链接链接已复制到粘贴板!
对问题进行故障排除的最佳方式是在客户端适配器和 Red Hat Single Sign-On Server 中打开 SAML 的调试。使用您的日志记录框架,将 org.keycloak.saml 软件包的日志级别设置为 DEBUG。启用这个端口可让您看到 SAML 请求和响应文档发送到服务器以及从服务器发送。
3.1.12. 多租户 复制链接链接已复制到粘贴板!
SAML 提供与 Multi Tenancy 相同的功能,这意味着单个目标应用程序(WAR)可以使用多个 Red Hat Single Sign-On 域进行保护。域可以位于同一红帽单点登录实例或不同的实例上。
要做到这一点,应用程序必须有多个 keycloak-saml.xml 适配器配置文件。
虽然您可以有多个 WAR 实例,但不同的适配器配置文件部署到不同的上下文路径,但这可能很不便,您可能还希望根据上下文路径以外的某些域选择域。
Red Hat Single Sign-On 使可以有一个自定义配置解析器,以便您可以选择每个请求使用哪些适配器配置。在 SAML 中,配置只在登录处理中非常感兴趣;一旦登录,会话会被身份验证,并且如果返回了 keycloak-saml.xml 并不重要。因此,为相同会话返回相同的配置是到达的正确方法。
为达成此目标,可创建 org.keycloak.adapters.saml.SamlConfigResolver 的实施。以下示例使用 Host 标头来定位正确的配置并加载它以及应用程序的 Java 类路径中的关联元素:
您还必须配置在 web.xml 中用于 keycloak.config.resolver context-param 的 SamlConfigResolver 实现: