<SP entityID="sp"
sslPolicy="ssl"
nameIDPolicyFormat="format"
forceAuthentication="true"
isPassive="false"
keepDOMAssertion="true"
autodetectBearerOnly="false">
...
</SP>
本指南包含 Keycloak SAML Galleon 功能包使用的 keycloak-saml.xml
配置文件的详细元素列表。
以下是 SP 元素属性的说明
<SP entityID="sp"
sslPolicy="ssl"
nameIDPolicyFormat="format"
forceAuthentication="true"
isPassive="false"
keepDOMAssertion="true"
autodetectBearerOnly="false">
...
</SP>
这是此客户端的标识符。IdP 需要此值来确定与之通信的客户端是谁。此设置是必需的。
这是适配器将强制执行的 SSL 策略。有效值为:ALL
、EXTERNAL
和 NONE
。对于 ALL
,所有请求都必须通过 HTTPS 进入。对于 EXTERNAL
,只有非私有 IP 地址必须通过 HTTPS 传输。对于 NONE
,不要求任何请求通过 HTTPS 传输。此设置是可选的。默认值为 EXTERNAL
。
SAML 客户端可以请求特定的 NameID Subject 格式。如果您想要特定格式,请填写此值。它必须是标准的 SAML 格式标识符:urn:oasis:names:tc:SAML:2.0:nameid-format:transient
。此设置是可选的。默认情况下,不请求特殊格式。
SAML 客户端可以请求用户重新进行身份验证,即使他们已经在 IdP 中登录。设置为 true
以启用。此设置是可选的。默认值为 false
。
SAML 客户端可以请求永远不要询问用户进行身份验证,即使他们未在 IdP 中登录。如果您想要这样做,请设置为 true
。不要与 forceAuthentication
一起使用,因为它们是相反的。此设置是可选的。默认值为 false
。
默认情况下,在某些平台上成功登录后会更改会话 ID,以堵塞安全攻击媒介。更改为 true
以禁用此功能。建议您不要关闭它。默认值为 false
。
如果您的应用程序同时为 Web 应用程序和 Web 服务(例如 SOAP 或 REST)提供服务,则应将其设置为 true。它允许您将 Web 应用程序的未经身份验证的用户重定向到 Keycloak 登录页面,但向未经身份验证的 SOAP 或 REST 客户端发送 HTTP 401
状态代码,因为他们无法理解重定向到登录页面。Keycloak 根据典型的标头(如 X-Requested-With
、SOAPAction
或 Accept
)自动检测 SOAP 或 REST 客户端。默认值为 false。
这设置了注销后显示的页面。如果页面是完整的 URL,例如 http://web.example.com/logout.html
,则用户在注销后使用 HTTP 302
状态代码重定向到该页面。如果指定了没有方案部分的链接,例如 /logout.jsp
,则在注销后显示该页面,无论它是否根据 web.xml 中的 security-constraint
声明位于受保护区域,并且该页面相对于部署上下文根进行解析。
应将此属性设置为 true,以使适配器将断言的 DOM 表示形式以原始形式存储在与请求关联的 SamlPrincipal
中。可以使用 principal 内的 getAssertionDocument
方法检索断言文档。当重放已签名的断言时,这尤其有用。返回的文档是解析 Keycloak 服务器收到的 SAML 响应生成的文档。此设置是可选的,其默认值为 false(文档未保存在 principal 中)。
如果 IdP 要求客户端应用程序(或 SP)对其所有请求进行签名,和/或如果 IdP 将加密断言,则必须定义用于执行此操作的密钥。对于客户端签名的文档,您必须同时定义用于对文档进行签名的私钥和公钥或证书。对于加密,您只需定义用于解密的私钥。
有两种方法来描述您的密钥。它们可以存储在 Java KeyStore 中,或者您可以将密钥直接复制/粘贴到 PEM 格式的 keycloak-saml.xml
中。
<Keys>
<Key signing="true" >
...
</Key>
</Keys>
Key
元素具有两个可选属性 signing
和 encryption
。当设置为 true 时,这些属性会告诉适配器密钥将用于什么。如果两个属性都设置为 true,则密钥将用于签名文档和解密加密的断言。您必须将这些属性中的至少一个设置为 true。
在 Key
元素中,您可以从 Java Keystore 加载您的密钥和证书。这在 KeyStore
元素中声明。
<Keys>
<Key signing="true" >
<KeyStore resource="/WEB-INF/keystore.jks" password="store123">
<PrivateKey alias="myPrivate" password="test123"/>
<Certificate alias="myCertAlias"/>
</KeyStore>
</Key>
</Keys>
以下是在 KeyStore
元素中定义的 XML 配置属性。
密钥库的文件路径。此选项是可选的。必须设置 file 或 resource 属性。
KeyStore 的 WAR 资源路径。这是在调用 ServletContext.getResourceAsStream() 方法中使用的路径。此选项是可选的。必须设置 file 或 resource 属性。
KeyStore 的密码。此选项是必需的。
如果您正在定义 SP 将用于签名文档的密钥,则还必须在 Java KeyStore 中指定对您的私钥和证书的引用。上面示例中的 PrivateKey
和 Certificate
元素定义了一个 alias
,该别名指向密钥库中的密钥或证书。密钥库需要额外的密码才能访问私钥。在 PrivateKey
元素中,您必须在 password
属性中定义此密码。
在 Key
元素中,您可以使用子元素 PrivateKeyPem
、PublicKeyPem
和 CertificatePem
直接声明您的密钥和证书。这些元素中包含的值必须符合 PEM 密钥格式。如果您使用 openssl
或类似的命令行工具生成密钥,则通常使用此选项。
<Keys>
<Key signing="true">
<PrivateKeyPem>
2341251234AB31234==231BB998311222423522334
</PrivateKeyPem>
<CertificatePem>
211111341251234AB31234==231BB998311222423522334
</CertificatePem>
</Key>
</Keys>
此元素是可选的。当创建从诸如 HttpServletRequest.getUserPrincipal()
之类的方法获得的 Java Principal 对象时,您可以定义 Principal.getName()
方法返回的名称。
<SP ...>
<PrincipalNameMapping policy="FROM_NAME_ID"/>
</SP>
<SP ...>
<PrincipalNameMapping policy="FROM_ATTRIBUTE" attribute="email" />
</SP>
policy
属性定义用于填充此值的策略。此属性的可能值为
此策略仅使用 SAML 主题值。这是默认设置
这将从服务器收到的 SAML 断言中声明的属性之一中提取值。您需要在 attribute
XML 属性中指定要使用的 SAML 断言属性的名称。
RoleIdentifiers
元素定义了应使用用户收到的断言中的哪些 SAML 属性作为 Jakarta EE Security Context 中用户的角色标识符。
<RoleIdentifiers>
<Attribute name="Role"/>
<Attribute name="member"/>
<Attribute name="memberOf"/>
</RoleIdentifiers>
默认情况下,Role
属性值将转换为 Jakarta EE 角色。某些 IdP 使用 member
或 memberOf
属性断言发送角色。您可以定义一个或多个 Attribute
元素来指定必须转换为角色的 SAML 属性。
RoleMappingsProvider
是一个可选元素,允许指定 SAML 适配器要使用的 org.keycloak.adapters.saml.RoleMappingsProvider
SPI 实现的 id 和配置。
当 Keycloak 用作 IDP 时,可以使用内置的角色映射器在将任何角色添加到 SAML 断言之前对其进行映射。但是,SAML 适配器可用于向第三方 IDP 发送 SAML 请求,在这种情况下,可能需要将从断言中提取的角色映射到 SP 所需的不同角色集。RoleMappingsProvider
SPI 允许配置可插拔的角色映射器,这些映射器可用于执行必要的映射。
提供程序的配置如下所示
...
<RoleIdentifiers>
...
</RoleIdentifiers>
<RoleMappingsProvider id="properties-based-role-mapper">
<Property name="properties.resource.location" value="/WEB-INF/role-mappings.properties"/>
</RoleMappingsProvider>
<IDP>
...
</IDP>
id
属性标识要使用哪个已安装的提供程序。Property
子元素可以多次使用,以指定提供程序的配置属性。
Keycloak 包括一个 RoleMappingsProvider
实现,该实现使用 properties
文件执行角色映射。此提供程序由 id properties-based-role-mapper
标识,并由 org.keycloak.adapters.saml.PropertiesBasedRoleMapper
类实现。
此提供程序依赖于两个配置属性,这些属性可用于指定将使用的 properties
文件的位置。首先,它检查是否已指定 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>
如果未设置 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>
properties
文件可以包含角色和主体作为键,以及以逗号分隔的零个或多个角色列表作为值。调用时,实现会迭代从断言中提取的角色集,并检查每个角色是否存在映射。如果角色映射到空角色,则将其丢弃。如果它映射到一组或多组不同的角色,则在结果集中设置这些角色。如果找不到角色的映射,则按原样将其包含在结果集中。
处理完角色后,实现会检查从断言中提取的主体是否包含 properties
文件条目。如果存在主体的映射,则将列为值的任何角色添加到结果集中。这允许将额外的角色分配给主体。
例如,假设提供程序已使用以下属性文件配置
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 替换。例如,传入的 'role A' 将显示为
role\u0020A=roleX,roleY
要添加自定义角色映射提供程序,只需实现 org.keycloak.adapters.saml.RoleMappingsProvider
SPI。有关更多详细信息,请参阅服务器开发人员指南中的 SAML Role Mappings SPI
部分。
IDP 元素中的所有内容都描述了 SP 与之通信的身份提供程序(身份验证服务器)的设置。
<IDP entityID="idp"
signaturesRequired="true"
signatureAlgorithm="RSA_SHA1"
signatureCanonicalizationMethod="http://www.w3.org/2001/10/xml-exc-c14n#">
...
</IDP>
以下是您可以在 IDP
元素声明中指定的属性配置选项。
这是 IDP 的颁发者 ID。此设置是必需的。
如果设置为 true
,则客户端适配器将对其发送给 IDP 的每个文档进行签名。此外,客户端将期望 IDP 将对发送给它的任何文档进行签名。此开关为所有请求和响应类型设置默认值,但您稍后会看到您可以对此进行细粒度控制。此设置是可选的,默认为 false
。
这是 IDP 期望签名文档使用的签名算法。允许的值为:RSA_SHA1
、RSA_SHA256
、RSA_SHA512
和 DSA_SHA1
。此设置是可选的,默认为 RSA_SHA256
。请注意,基于 SHA1
的算法已被弃用,并且将来可能会删除。我们建议使用一些比 *_SHA1
更安全的算法。此外,对于 *_SHA1
算法,如果 SAML 服务器(通常是 Keycloak)在 Java 17 或更高版本上运行,则验证签名不起作用。
这是 IDP 期望签名文档使用的签名规范化方法。此设置是可选的。默认值为 http://www.w3.org/2001/10/xml-exc-c14n#
,对于大多数 IDP 来说应该足够好。
用于检索 IDP 元数据的 URL,目前仅用于定期获取签名和加密密钥,这允许在 IDP 上循环使用这些密钥,而无需在 SP 端进行手动更改。
AllowedClockSkew
可选子元素定义了 IDP 和 SP 之间允许的时钟偏差。默认值为 0。
<AllowedClockSkew unit="MILLISECONDS">3500</AllowedClockSkew>
可以为此元素的值定义附加的时间单位。允许的值为 MICROSECONDS、MILLISECONDS、MINUTES、NANOSECONDS 和 SECONDS。这是可选的。默认值为 SECONDS
。
SingleSignOnService
子元素定义了 IDP 的登录 SAML 端点。当客户端适配器想要登录时,它将通过此元素中的设置格式化的请求发送到 IDP。
<SingleSignOnService signRequest="true"
validateResponseSignature="true"
requestBinding="post"
bindingUrl="url"/>
以下是您可以在此元素上定义的配置属性
客户端是否应签名 authn 请求?此设置是可选的。默认为 IDP signaturesRequired
元素值。
客户端是否应期望 IDP 签名从 authn 请求发送回的断言响应文档?此设置是可选的。默认为 IDP signaturesRequired
元素值。
这是用于与 IDP 通信的 SAML 绑定类型。此设置是可选的。默认值为 POST
,但您也可以将其设置为 REDIRECT
。
SAML 允许客户端请求它希望 authn 响应使用的绑定类型。此值可以是 POST
或 REDIRECT
。此设置是可选的。默认情况下,客户端不会请求响应的特定绑定类型。
断言消费者服务 (ACS) 的 URL,IDP 登录服务应将响应发送到此处。此设置是可选的。默认情况下,它未设置,依赖于 IdP 中的配置。设置后,它必须以 /saml
结尾,例如 http://sp.domain.com/my/endpoint/for/saml
。此属性的值在 SAML AuthnRequest
消息的 AssertionConsumerServiceURL
属性中发送。此属性通常与 responseBinding
属性一起使用。
这是客户端将请求发送到的 IDP 登录服务的 URL。此设置是必需的。
SingleLogoutService
子元素定义了 IDP 的注销 SAML 端点。当客户端适配器想要注销时,它将通过此元素中的设置格式化的请求发送到 IDP。
<SingleLogoutService validateRequestSignature="true"
validateResponseSignature="true"
signRequest="true"
signResponse="true"
requestBinding="redirect"
responseBinding="post"
postBindingUrl="posturl"
redirectBindingUrl="redirecturl">
客户端是否应签名其向 IDP 发出的注销请求?此设置是可选的。默认为 IDP signaturesRequired
元素值。
客户端是否应签名其发送给 IDP 请求的注销响应?此设置是可选的。默认为 IDP signaturesRequired
元素值。
客户端是否应期望来自 IDP 的签名注销请求文档?此设置是可选的。默认为 IDP signaturesRequired
元素值。
客户端是否应期望来自 IDP 的签名注销响应文档?此设置是可选的。默认为 IDP signaturesRequired
元素值。
这是用于将 SAML 请求通信到 IDP 的 SAML 绑定类型。此设置是可选的。默认值为 POST
,但您也可以将其设置为 REDIRECT。
这是用于将 SAML 响应通信到 IDP 的 SAML 绑定类型。此值可以是 POST
或 REDIRECT
。此设置是可选的。默认值为 POST
,但您也可以将其设置为 REDIRECT
。
这是使用 POST 绑定时 IDP 注销服务的 URL。如果使用 POST
绑定,则此设置是必需的。
这是使用 REDIRECT 绑定时 IDP 注销服务的 URL。如果使用 REDIRECT 绑定,则此设置是必需的。
IDP 的 Keys 子元素仅用于定义用于验证 IDP 签名的文档的证书或公钥。它的定义方式与SP 的 Keys 元素相同。但是,同样,您只需定义一个证书或公钥引用。请注意,如果 IDP 和 SP 分别由 Keycloak 服务器和适配器实现,则无需指定用于签名验证的密钥,请参见下文。
可以配置 SP 以自动从发布的证书中获取用于 IDP 签名验证的公钥,前提是 SP 和 IDP 均由 Keycloak 实现。这可以通过删除 Keys 子元素中签名验证密钥的所有声明来完成。如果 Keys 子元素随后保持为空,则可以完全省略它。然后,密钥由 SP 从 SAML 描述符自动获取,其位置从IDP SingleSignOnService 子元素中指定的 SAML 端点 URL 派生。用于 SAML 描述符检索的 HTTP 客户端的设置通常不需要额外的配置,但是可以在IDP HttpClient 子元素中进行配置。
也可以指定多个密钥用于签名验证。这可以通过在 Keys 子元素中声明多个 signing
属性设置为 true
的 Key 元素来完成。这在 IDP 签名密钥轮换的情况下非常有用:通常存在一个过渡期,在此期间,新的 SAML 协议消息和断言使用新密钥签名,但仍应接受以前密钥签名的消息和断言。
无法配置 Keycloak 同时自动获取用于签名验证的密钥并定义其他静态签名验证密钥。
<IDP entityID="idp">
...
<Keys>
<Key signing="true">
<KeyStore resource="/WEB-INF/keystore.jks" password="store123">
<Certificate alias="demo"/>
</KeyStore>
</Key>
</Keys>
</IDP>
HttpClient
可选子元素定义了 HTTP 客户端的属性,该客户端用于在启用时通过 IDP 的 SAML 描述符自动获取包含用于 IDP 签名验证的公钥的证书。
<HttpClient connectionPoolSize="10"
disableTrustManager="false"
allowAnyHostname="false"
clientKeystore="classpath:keystore.jks"
clientKeystorePassword="pwd"
truststore="classpath:truststore.jks"
truststorePassword="pwd"
proxyUrl="http://proxy/"
socketTimeout="5000"
connectionTimeout="6000"
connectionTtl="500" />
此配置选项定义了应池化到 Keycloak 服务器的连接数。这是可选的。默认值为 10
。
如果 Keycloak 服务器需要 HTTPS 并且此配置选项设置为 true
,则您不必指定信任库。此设置仅应在开发期间使用,绝不能在生产中使用,因为它将禁用 SSL 证书的验证。这是可选的。默认值为 false
。
如果 Keycloak 服务器需要 HTTPS 并且此配置选项设置为 true
,则 Keycloak 服务器的证书将通过信任库进行验证,但不执行主机名验证。此设置仅应在开发期间使用,绝不能在生产中使用,因为它将部分禁用 SSL 证书的验证。此设置在测试环境中可能很有用。这是可选的。默认值为 false
。
该值是信任库文件的文件路径。如果路径以 classpath:
为前缀,则将从部署的类路径中获取信任库。用于与 Keycloak 服务器的传出 HTTPS 通信。发出 HTTPS 请求的客户端需要一种方法来验证他们正在与之通信的服务器的主机。这就是信任库的作用。密钥库包含一个或多个受信任的主机证书或证书颁发机构。您可以通过提取 Keycloak 服务器 SSL 密钥库的公共证书来创建此信任库。除非 disableTrustManager
为 true
,否则这是必需的。
信任库的密码。如果设置了 truststore
并且信任库需要密码,则这是必需的。
这是密钥库文件的文件路径。当适配器向 Keycloak 服务器发出 HTTPS 请求时,此密钥库包含用于双向 SSL 的客户端证书。这是可选的。
客户端密钥库和客户端密钥的密码。如果设置了 clientKeystore
,则这是必需的。
用于 HTTP 连接的 HTTP 代理的 URL。这是可选的。
建立连接后,套接字等待数据的超时时间,以毫秒为单位。两个数据包之间最大不活动时间。超时值零被解释为无限超时。负值被解释为未定义(如果适用,则为系统默认值)。默认值为 -1
。这是可选的。
与远程主机建立连接的超时时间,以毫秒为单位。超时值零被解释为无限超时。负值被解释为未定义(如果适用,则为系统默认值)。默认值为 -1
。这是可选的。
客户端的连接生存时间,以毫秒为单位。小于或等于零的值被解释为无限值。默认值为 -1
。这是可选的。