第 3 章 使用 SAML 保护应用程序和服务
本节论述了如何使用 Red Hat Single Sign-On 客户端适配器或通用 SAML 供应商库通过 SAML 保护应用程序和服务。
3.1. Java 适配器 复制链接链接已复制到粘贴板!
Red Hat Single Sign-On 附带了一系列不同的 Java 应用程序适配器。选择正确的适配器取决于目标平台。
3.1.1. 常规适配器配置 复制链接链接已复制到粘贴板!
Red Hat Single Sign-On 支持的每个 SAML 客户端适配器都可以通过简单的 XML 文本文件进行配置。它可能类似如下:
其中一些配置切换可能特定于适配器,一些在所有适配器中都很常见。对于 Java 适配器,您可以使用 ${…} 213ure 作为系统属性替换。例如,${jboss.server.config.dir}。
3.1.1.1. SP 元素 复制链接链接已复制到粘贴板!
以下是 SP 元素属性的说明:
- entityID
- 这是此客户端的标识符。IdP 需要这个值来确定正在与之通信的客户端。此设置是 REQUIRED。
- sslPolicy
-
这是适配器将强制执行的 SSL 策略。有效值为:
ALL、EXTERNAL和NONE。对于all,所有请求都必须通过 HTTPS 访问。对于EXTERNAL,只有非私有 IP 地址必须通过 HTTPS 出现在线上。对于NONE,不需要通过 HTTPS 发出请求。此设置选项为 选项。默认值为EXTERNAL。 - nameIDPolicyFormat
-
SAML 客户端可以请求特定的 NameID 主题格式。如果您想要一个特定的格式,请填写这个值。它必须是标准的 SAML 格式标识符:urn
:oasis:names:tc:SAML:2.0:name-format:transient。此设置选项为 选项。默认情况下,没有请求特殊格式。 - forceAuthentication
-
SAML 客户端可以请求用户被重新验证,即使他们已在 IdP 中登录。把它设置为
true来启用。此设置选项为 选项。默认值为false。 - isPassive
-
SAML 客户端可以请求用户永远不会被要求验证,即使用户没有在 IdP 中登录。如果您想要这样做,则将其设置为
true。请勿与forceAuthentication一起使用,因为它们相反。此设置选项为 选项。默认值为false。 - turnOffChangeSessionIdOnLogin
-
在某些平台上成功登录时,会话 ID 被修改,以插入安全攻击向量。将此选项更改为
true以禁用此功能。建议您不要关闭它。默认值为false。 - autodetectBearerOnly
-
如果您的应用程序同时为 Web 应用程序和 Web 服务(如 SOAP 或 REST)提供,则此项应设为 true。它允许您将 Web 应用的未经身份验证的用户重定向到 Red Hat Single Sign-On 登录页面,但向未经身份验证的 SOAP 或 REST 客户端发送 HTTP
401状态代码,而不是将它们了解到登录页面。Red Hat Single Sign-On auto-detects SOAP 或 REST 客户端基于X-Requested-With、SOAPAction或Accept等典型标头。默认值为 false。 - logoutPage
-
这会将页面设置为在注销后显示。如果页面是完整的 URL,如
http://web.example.com/logout.html,则在使用 HTTP302状态代码注销后,用户会被重定向到该页面。如果指定了没有方案部分的链接,如/logout.jsp,则该页会在注销 后显示,无论它依赖于 web.xml 中的security-constraint声明,且页面针对部署上下文 root 解析。 - keepDOMAssertion
-
此属性应设置为 true,以便适配器将断言的 DOM 表示存储在与请求关联的
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 元素有两个可选属性 。当设置为 true 时,这些会告知适配器将什么密钥用于什么。如果这两个属性都设为 true,那么密钥将同时用于签名文档和解密加密断言。您必须至少将其中一个属性设置为 true。
签名和加密
3.1.1.2.1. keystore 元素 复制链接链接已复制到粘贴板!
在 Key 元素中,您可以从 Java 密钥存储加载您的密钥和证书。这在 KeyStore 元素中声明。
以下是使用 KeyStore 元素定义的 XML 配置属性。
- file
- 密钥存储的文件路径。此选项是 选项。必须设置 file 或 resource 属性。
- resource
- KeyStore 的 WAR 资源路径。这是对 ServletContext.getResourceAsStream ()的方法调用时使用的路径。此选项是 选项。必须设置 file 或 resource 属性。
- password
- KeyStore 的密码。此选项是 REQUIRED。
如果您要定义 SP 将用来记录文档的密钥,还必须在 Java KeyStore 中指定对私钥和证书的引用。上例中的 PrivateKey 和证书元素定义了一个指向密钥存储内密钥或证书的别名。 密钥存储需要额外的密码才能访问私钥。在 PrivateKey 元素中,您必须在 password 属性中定义此密码。
3.1.1.2.2. 密钥 PEMS 复制链接链接已复制到粘贴板!
在 Key 元素中,您直接使用 PrivateKeyPem、PublicKeyPem 和 CertificatePem 的子元素声明您的密钥和证书。这些元素中包含的值必须符合 PEM 密钥格式。如果您使用 openssl 或类似的命令行工具生成密钥,您通常会使用这个选项。
3.1.1.3. SP PrincipalNameMapping element 复制链接链接已复制到粘贴板!
这个元素是可选的。在创建从 HttpServletRequest.getUserPrincipal () 等方法中获取的 Java Principal 对象时,您可以定义 Principal.getName () 方法返回的名称。
policy 属性定义用于填充此值的策略。这个属性的可能值有:
- FROM_NAME_ID
- 这个策略只使用任何 SAML 主题值。这是默认设置
- FROM_ATTRIBUTE
-
这将从从服务器接收的 SAML 断言中声明的其中一个属性中提取值。您需要指定在属性 XML 属性中使用的 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>
默认情况下 ,角色 属性值转换为 Jakarta EE 角色。有些 IdP 使用 member 或 memberOf 属性断言来发送角色。您可以定义一个或多个属性元素,以指定必须将哪些 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. 基于属性的角色映射供应商 复制链接链接已复制到粘贴板!
红帽单点登录包括 RoleMappingsProvider 实施,它利用属性文件执行 角色映射。此提供程序由 id properties-based-role-mapper 标识,它由 org.keycloak.adapters.saml.PropertiesBasedRoleMapper 类实施。
此提供程序依赖于两个配置属性,可用于指定要使用的 属性 文件的位置。首先,它利用配置的值来检查 properties.file.location 属性是否已指定,以 在文件系统中 定位属性文件。如果所配置的文件不在,则提供程序将引发 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.locationproperties.resource.location 属性,使用配置的值从 WAR 资源加载属性文件。如果这个配置属性也不存在,则提供程序会尝试默认尝试从 /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>
属性 文件可以包含 roles 和 principals 作为键,以及用逗号分开的零个或多个角色列表,作为值。调用时,实施会迭代从断言中提取的角色集合,并在存在映射时对每个角色进行检查。如果角色映射到空角色,它将被丢弃。如果映射到一个或多个不同角色的集合,则会在结果集中设置这些角色。如果没有为角色找到映射,它将包含在结果集合中。
处理角色后,实施会检查从断言中提取的主体是否包含条目 属性文件。如果存在主体的映射,作为值列出的任何角色都会添加到结果集中。这允许将额外角色分配给主体。
例如,我们假设供应商已配置有以下属性文件:
roleA=roleX,roleY roleB= kc_user=roleZ
roleA=roleX,roleY
roleB=
kc_user=roleZ
如果从具有 roleA、roleB 和 roleC 的断言器提取了主体的 kc_user,则分配给主体的最终角色集为 roleC、roleX、roleY 和 roleZ,因为 roleA 都被映射到 roleX 和 roleY, roleB 映射到空角色(因此被丢弃),roleC 会被原样使用,最后将一个额外的角色添加到 kc_user 主体(roleZ)。
注: 要在角色名称中使用空格进行映射,请使用 unicode 替换空间。例如,传入 'role 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 元素 复制链接链接已复制到粘贴板!
IDP 元素中的所有内容都描述了 SP (身份验证服务器)与 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 需要使用签名文档的签名规范方法。此设置选项为 选项。默认值为
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
-
客户端是否应该为 authn 请求签名?此设置选项为 选项。默认为 IDP
签名必需元素值的任何 IDP。 - validateResponseSignature
-
客户端是否应该为 IDP 签署从 auhtn 请求发回的断言响应文档?此设置 选项选项.默认为 IDP
签名必需元素值的任何 IDP。 - requestBinding
-
这是用于与 IDP 通信的 SAML 绑定类型。此设置选项为 选项。默认值为
POST,但您也可以将其设置为REDIRECT。 - responseBinding
-
SAML 允许客户端请求希望 authn 响应的绑定类型。这个值可以是
POST或REDIRECT。此设置选项为 选项。默认为客户端不会请求特定的绑定类型响应。 - assertionConsumerServiceUrl
-
IDP 登录服务(ACS)的断言使用者服务(ACS)的 URL 应向其中发送响应。此设置选项为 选项。默认情况下取消设置,它依赖于 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 发出的请求?此设置选项为 选项。默认为 IDP
签名必需元素值的任何 IDP。 - signResponse
-
客户端是否应该注销它发送到 IDP 请求的响应?此设置选项为 选项。默认为 IDP
签名必需元素值的任何 IDP。 - validateRequestSignature
-
客户端是否应该从 IDP 中记录已签名的请求文档?此设置选项为 选项。默认为 IDP
签名必需元素值的任何 IDP。 - validateResponseSignature
-
客户端是否期望从 IDP 进行签名的注销响应文档?此设置选项为 选项。默认为 IDP
签名必需元素值的任何 IDP。 - requestBinding
-
这是用于向 IDP 发送 SAML 请求的 SAML 绑定类型。此设置选项为 选项。默认值为
POST,但您也可以将其设置为 REDIRECT。 - responseBinding
-
这是用于向 IDP 发送 SAML 响应的 SAML 绑定类型。这个值可以是
POST或REDIRECT。此设置选项为 选项。默认值为POST,但您也可以将其设置为REDIRECT。 - postBindingUrl
-
这是使用 POST 绑定时 IDP 注销服务的 URL。如果使用
POST绑定,则此设置是 REQUIRED。 - redirectBindingUrl
- 这是使用 REDIRECT 绑定时 IDP 注销服务的 URL。如果使用 REDIRECT 绑定,则此设置是 REQUIRED。
3.1.1.10. IDP 键子元素 复制链接链接已复制到粘贴板!
IDP 的 Keys 子元素仅用于定义用来验证 IDP 签名的证书或公钥。它的定义方式与 SP 的 Keys 元素 相同。但是,您只需要定义一个证书或公钥引用。请注意,如果 Red Hat Single Sign-On server 和 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 子元素中声明将 签名 属性设置为 true 的多个 Key 元素来完成。当 IDP 签名密钥轮转时,这很有用:当新的 SAML 协议消息和断言使用新密钥签名时,通常会有一个过渡周期,但应该仍然可以接受之前密钥签名的。
无法将 Red Hat Single Sign-On 配置为自动获取签名验证的密钥,并定义额外的静态签名验证密钥。
3.1.1.11. IDP HttpClient 子元素 复制链接链接已复制到粘贴板!
HttpClient 可选子元素定义了用于自动获取证书的 HTTP 客户端的属性,包含通过 IDP 的 SAML 描述符 在启用 时通过 IDP 进行签名验证的公钥。
- connectionPoolSize
-
此配置选项定义了与 Red Hat Single Sign-On 服务器的连接数量。这是 选项。默认值为
10。 - disableTrustManager
-
如果 Red Hat Single Sign-On 服务器需要 HTTPS,且这个配置选项被设置为
true,则不必指定信任存储。此设置仅应在开发期间使用,且不应 在生产环境中使用,因为它将禁用 SSL 证书的验证。这是 选项。默认值为false。 - allowAnyHostname
-
如果 Red Hat Single Sign-On 服务器需要 HTTPS,且这个配置选项被设置为
true,Red Hat Single Sign-On 服务器的证书通过 truststore 验证,但没有进行主机名验证。此设置仅应在开发期间使用,且不应在生产环境中使用,因为它部分禁用 SSL 证书的验证。在测试环境中,此集合可能有用。这是 选项。默认值为false。 - truststore
-
该值是 truststore 文件的文件路径。如果您为带有
classpath 的路径添加前缀:,则信任存储将从部署的类路径中获取。用于向 Red Hat Single Sign-On 服务器的外向 HTTPS 通信。进行 HTTPS 请求的客户端需要一种方式来验证所讨论的服务器主机。这是信任者的作用。密钥存储包含一个或多个可信主机证书或证书颁发机构。您可以通过提取红帽单点登录服务器 SSL 密钥存储的公共证书来创建此信任存储。这是 REQUIRED,除非禁用TrustManager为true。 - truststorePassword
-
truststore 的密码。如果设置了
truststore,则 REQUIRED 为 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 子系统。
然后,在 web.xml 中提供 keycloak 配置 /WEB-INF/keycloak-saml.xml 文件,并将 auth-method 更改为 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 脚本在应用服务器配置中启用 Red Hat Single Sign-On SAML 子系统:
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 将此命令用于 JBoss EAP 7.0 和 EAP 6.4
cd $JBOSS_HOME ./bin/boss-cli.sh -c --file=bin/adapter-install-saml.cli
$ cd $JBOSS_HOME $ ./bin/boss-cli.sh -c --file=bin/adapter-install-saml.cliCopy to Clipboard Copied! Toggle word wrap Toggle overflow 注意也可以在 JBoss EAP 7.1 或更高版本中使用旧的非Elytron 适配器,这意味着您可以在这些版本中使用
adapter-install-saml.cli。但是,我们建议使用较新的 Elytron 适配器。该脚本将添加扩展、子系统和可选 security-domain,如下所述。
当您需要在安全 Web 层中创建的安全上下文传播到您正在调用的 EJB (其他 EE 组件)时创建的安全上下文时,应结合使用 keycloak 安全域。否则,这个配置是可选的。
安全上下文自动传播到 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。此设置表示,只有在请求来自同一域中时,才会将 Cookie 发送到应用程序。此行为可能会影响 SAML POST 绑定,这些绑定可能无法正常工作。要保留 SAML 适配器的完整功能,我们建议将容器创建的 JSESSIONID cookie 的 SameSite 值设置为 None。这样做可能会导致为容器的每个请求重置 Red Hat Single Sign-On 的会话。
为了避免将 SameSite 属性设置为 None,请考虑切换到 REDIRECT 绑定(如果可以接受),或者不需要进行这个临时解决方案的 OIDC 协议。
要将 Wildfly/EAP 中的 JSESSIONID cookie 的 SameSite 值设置为 None,请将包含以下内容的文件 undertow-handlers.conf 添加到您的应用程序的 WEB-INF 目录:
samesite-cookie(mode=None, cookie-pattern=JSESSIONID)
samesite-cookie(mode=None, cookie-pattern=JSESSIONID)
对此配置的支持在 19.1.0 版本 19.1.0 的 Wildfly 中提供。
3.1.4. 从 RPM 安装 JBoss EAP 7 适配器 复制链接链接已复制到粘贴板!
在 Red Hat Enterprise Linux 7 中,术语频道被使用术语仓库替代。在这些说明中,仅使用术语存储库。
前提条件
您必须订阅 JBoss EAP 7 存储库,然后才能从 RPM 安装 EAP 7 适配器。
- 使用 Red Hat Subscription Manager 确保您的 Red Hat Enterprise Linux 系统已注册到您的帐户。如需更多信息,请参阅 红帽订阅管理文档。
如果您已订阅了另一个 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_5
$ sudo yum install eap7-keycloak-saml-adapter-sso7_5Copy to Clipboard Copied! Toggle word wrap Toggle overflow 在 Red Hat Enterprise Linux 8 中安装:
sudo dnf install eap7-keycloak-adapter-sso7_5
$ sudo dnf install eap7-keycloak-adapter-sso7_5Copy 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 适配器 复制链接链接已复制到粘贴板!
在 Red Hat Enterprise Linux 7 中,术语频道被使用术语仓库替代。在这些说明中,仅使用术语存储库。
前提条件
您必须订阅 JBoss EAP 6 存储库,然后才能从 RPM 安装 EAP 6 适配器。
- 使用 Red Hat Subscription Manager 确保您的 Red Hat Enterprise Linux 系统已注册到您的帐户。如需更多信息,请参阅 红帽订阅管理文档。
- 如果您已订阅了另一个 JBoss EAP 存储库,必须先退订该存储库。
使用以下命令,使用红帽订阅管理器订阅 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_5-eap6
$ sudo yum install keycloak-saml-adapter-sso7_5-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 适配器配置文件。此配置文件的格式在 General Adapter Config 部分中描述。
接下来,您必须在 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 子系统从外部保护它。虽然您不必将 KEYCLOAK-SAML 指定为 auth-method,但在 web.xml 中定义 security-constraints。但是,您不必创建一个 WEB-INF/keycloak-saml.xml 文件。此元数据在服务器的 domain.xml 或 standalone.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 过滤器的集群应用程序时,Backchannel logout 当前无法正常工作。
Red Hat Single Sign-On 过滤器具有与其他适配器相同的配置参数,但您必须将其定义为过滤 initparams 而不是上下文参数。
如果您有不同的安全且不安全的 url 模式,可以定义多个过滤器映射。
您必须有一个包含 /saml 的过滤器映射。此映射覆盖所有服务器回调。
使用 IdP 注册 SP 时,您必须注册 http[s]://hostname/{context-root}/saml 作为 Assert Consumer Service URL 和 Single Logout Service URL。
要使用此过滤器,请将此 maven 工件包括在您的 WAR poms 中:
<dependency> <groupId>org.keycloak</groupId> <artifactId>keycloak-saml-servlet-filter-adapter</artifactId> <version>15.0.8.redhat-00001</version> </dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-servlet-filter-adapter</artifactId>
<version>15.0.8.redhat-00001</version>
</dependency>
要使用 Multi Tenancy the keycloak.config.resolver 参数,应该作为过滤器参数传递。
3.1.7. 使用身份提供程序注册 复制链接链接已复制到粘贴板!
对于基于 servlet 的适配器,您注册了断言使用者服务 URL 和单个注销服务的端点必须是附加到 servlet 应用的基本 URL,即 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,用于可分发的应用程序。作为前提条件,HTTP 会话需要在集群间发布(例如,应用程序在应用程序的 web.xml中被标记为 < distributable /> 标签)。
要启用这个功能,请在 /WEB_INF/web.xml 文件中添加以下部分:
对于 EAP 7,Wildic 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。缓存的名称可以被上下文参数 keycloak.sessionIdMapperUpdater.infinispan.cacheName 覆盖。包含缓存的缓存容器与包含部署会话缓存的缓存容器相同,但可以通过上下文参数 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 () 返回一个 Principal 对象,您可以将其输入到名为 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 这个对象为: org.keycloak.adapters.saml.SamlAuthenticationError。此类可以向您说明发生什么情况。如果没有设置此属性,则适配器不负责错误代码。
3.1.11. 故障排除 复制链接链接已复制到粘贴板!
解决问题的方法是,在客户端适配器和 Red Hat Single Sign-On 服务器中为 SAML 启用调试。使用您的日志记录框架,将 org.keycloak.saml 软件包的日志级别设置为 DEBUG。完成此操作后,您可以查看正在发送到和从服务器发送的 SAML 请求和响应文档。
3.1.12. 多租户 复制链接链接已复制到粘贴板!
SAML 为 多 密度提供与 OIDC 相同的功能,即单个目标应用程序(WAR)可以使用多个 Red Hat Single Sign-On 域进行保护。域可以位于同一红帽单点登录实例或不同的实例上。
为此,应用必须具有多个 keycloak-saml.xml 适配器配置文件。
虽然您可能有多个 WAR 实例,且不同的适配器配置文件部署到不同的上下文路径,但这可能会不方便,而且您可能还希望根据上下文路径以外的某些域进行选择。
Red Hat Single Sign-On 可以有自定义配置解析器,以便您可以为每个请求选择哪个适配器配置。在 SAML 中,配置只对登录处理非常感兴趣;一旦登录后,会话将进行身份验证,如果返回 keycloak-saml.xml 返回的 keycloak-saml.xml,则会话将不重要。因此,返回同一会话配置是达到的正确方法。
为此,可创建 org.keycloak.adapters.saml.SamlConfigResolver 的实现。以下示例使用 Host 标头来查找正确的配置并加载它以及应用程序的 Java 类路径中的关联元素:
您还必须配置用于 web.xml 中的 keycloak.config.resolver context-param 的 SamlConfigResolver 实现: