搜索

8.5. X.509 客户端证书用户身份验证

download PDF

如果您已将服务器配置为使用 mutual SSL 身份验证,则 Red Hat Single Sign-On 支持使用 X.509 客户端证书登录。

典型的工作流:

  • 客户端通过 SSL/TLS 频道发送身份验证请求。
  • 在 SSL/TLS 握手期间,服务器和客户端会交换其 x.509/v3 证书。
  • 容器(JBoss EAP)验证证书 PKIX 路径和证书到期日期。
  • X.509 客户端证书验证器使用以下方法之一验证客户端证书:

    • 使用 CRL 或 CRL 分发点检查证书撤销状态。
    • 使用 OCSP (在线证书状态协议)检查证书撤销状态。
    • 验证证书中的密钥是否与预期的密钥匹配。
    • 验证证书中的扩展密钥是否与预期的扩展密钥匹配。
  • 如果这些检查中有任何一个失败,x.509 身份验证会失败。否则,身份验证器会提取证书身份并将其映射到现有用户。

当证书映射到现有用户时,行为会根据身份验证流来剥离:

  • 在浏览器流中,服务器会提示用户确认其身份或使用用户名和密码登录。
  • 在 Direct Grant 流中,服务器会登录到用户。
重要

请注意,Web 容器负责验证证书 PKIX 路径。Red Hat Single Sign-On 一侧的 X.509 验证器只提供对检查证书过期、证书撤销状态和密钥使用的额外支持。如果您在使用在反向代理后部署的 Red Hat Single Sign-On,请确保您的反向代理配置为验证 PKIX 路径。如果您不使用反向代理和用户直接访问 JBoss EAP,您应该象 JBoss EAP 一样确保验证 PKIX 路径,只要它进行了配置,如下所示:

8.5.1. 功能

支持的证书身份源:

  • 使用正则表达式匹配 SubjectDN
  • X500 Subject 的 email 属性
  • X500 使用者电子邮件地址来自主题备用名称(RFC822Name 常规名称)
  • X500 对象来自主题备用名称扩展的其他名称。这个其他名称通常是 User Principal Name (UPN)。
  • X500 Subject 的 Common Name 属性
  • 使用正则表达式匹配 IssuerDN
  • 证书序列号
  • 证书 Serial Number 和 IssuerDN
  • SHA-256 证书指纹
  • PEM 格式的完整证书

8.5.1.1. 正则表达式

Red Hat Single Sign-On 使用正则表达式作为过滤器从 Subject DN 或 Issuer DN 中提取证书身份。例如,此正则表达式与 email 属性匹配:

emailAddress=(.*?)(?:,|$)

如果将 Identity Source 设置为 Match SubjectDN using regular expressionMatch IssuerDN using regular expression,会应用正则表达式过滤。

8.5.1.1.1. 将证书身份映射到现有用户

证书身份映射可以将提取的用户身份映射到现有用户的用户名、电子邮件或自定义属性,其值与证书身份匹配。例如,将 身份源 设置为 Subject 的电子邮件 或用户映射方法为 Username 或 email,使 X.509 客户端证书验证器使用证书主题 DN 中的 email 属性作为搜索条件,因为按用户名或电子邮件搜索现有用户。

重要
  • 如果您在 realm 设置中禁用 带有电子邮件 的登录,则同一规则适用于证书身份验证。用户无法使用 email 属性登录。
  • 使用 证书 Serial Number 和 IssuerDN 作为身份源需要两个序列号和 IssuerDN 的自定义属性。
  • SHA-256 证书指纹 是 SHA-256 证书指纹的小写十六进制表示。
  • 使用 PEM 格式的完整证书 作为身份源仅限于映射到外部联合源(如 LDAP)的自定义属性。由于有长限制,Red Hat Single Sign-On 无法将证书存储在其数据库中,因此,如果是 LDAP,您必须启用 Always Read Value From LDAP
8.5.1.1.2. 扩展证书验证
  • 使用 CRL 撤销状态检查。
  • 使用 CRL/Distribution Point 撤销状态检查。
  • 使用 OCSP/Responder URI 撤销状态检查。
  • 证书密钥验证.
  • 证书扩展密钥验证.

8.5.2. 启用 X.509 客户端证书用户身份验证

以下小节介绍了如何配置 JBoss EAP/Undertow 和红帽单点登录服务器以启用 X.509 客户端证书身份验证。

8.5.2.1. 在 JBoss EAP 中启用 mutual SSL

如果在 JBoss EAP 中启用 SSL 的说明,请参阅启用 SSL

  • 打开 RHSSO_HOME/standalone/configuration/standalone.xml,再添加一个新域:
<security-realms>
    <security-realm name="ssl-realm">
        <server-identities>
            <ssl>
                <keystore path="servercert.jks"
                          relative-to="jboss.server.config.dir"
                          keystore-password="servercert password"/>
            </ssl>
        </server-identities>
        <authentication>
            <truststore path="truststore.jks"
                        relative-to="jboss.server.config.dir"
                        keystore-password="truststore password"/>
        </authentication>
    </security-realm>
</security-realms>
ssl/keystore
ssl 元素包含 密钥存储 元素,其中包含从 JKS 密钥存储加载服务器公钥对的详细信息。
ssl/keystore/path
JKS 密钥存储的路径。
ssl/keystore/relative-to
密钥存储路径相对于的路径。
ssl/keystore/keystore-password
打开密钥存储的密码。
SSL/keystore/alias (可选)
密钥存储中的条目的别名。如果密钥存储包含多个条目,则设置。
SSL/keystore/key-password (可选)
私钥密码与密钥存储密码不同。
authentication/truststore
定义如何加载信任存储,以验证入站/外连接的远程端提供的证书。通常,truststore 包含一组可信 CA 证书。
authentication/truststore/path
JKS 密钥存储的路径,包含可信证书颁发机构的证书。
authentication/truststore/relative-to
truststore 路径的路径是相对路径的。
authentication/truststore/keystore-password
打开信任存储的密码。

8.5.2.2. 启用 HTTPS 侦听器

有关在 WildFly 中启用 HTTPS 的说明,请参阅 HTTPS Listener

  • 添加 <https-listener> 元素。
<subsystem xmlns="urn:jboss:domain:undertow:12.0">
	....
    <server name="default-server">
	    <https-listener name="default"
                        socket-binding="https"
                        security-realm="ssl-realm"
                        verify-client="REQUESTED"/>
    </server>
</subsystem>
https-listener/security-realm
这个值必须与上一节中的域的名称匹配。
https-listener/verify-client
如果设置为 REQUESTED,则服务器会选择性地询问客户端证书。如果设置为 REQUIRED,则服务器将拒绝入站连接(如果没有提供客户端证书)。

8.5.3. 在浏览器流中添加 X.509 客户端证书验证

  1. 在菜单中,单击 Authentication
  2. 点 "Browser" 流。
  3. 单击 Copy,以制作内置"Browser"流的副本。
  4. 输入副本的名称。
  5. 确定
  6. Add policy 下拉列表中的 copy。
  7. 单击 Add execution
  8. 点击 "X509/Validate Username Form"。
  9. Save

    X509 执行

    X509 Execution

  10. 点击上箭头按钮将"X509/Validate Username Forms"移到"Browser Forms"执行。
  11. 将要求设置为"ALTERNATIVE"。

    X509 浏览器流

    X509 Browser Flow

  12. 单击 Bindings 选项卡。
  13. 点击 Browser Flow 下拉列表。
  14. 从下拉列表中选择浏览器流的副本。
  15. Save

    X509 浏览器流绑定

    X509 Browser Flow Bindings

8.5.4. 配置 X.509 客户端证书验证

X509 配置

X509 Configuration

用户身份源
定义用于从客户端证书提取用户身份的方法。
启用规范 DN 表示
定义是否使用规范格式来确定可识别的名称。官方 Java API 文档描述了格式。这个选项 使用正则表达式对两个用户身份来源 Match SubjectDN 的影响,仅使用 正则表达式。在设置新的 Red Hat Single Sign-On 实例时启用这个选项。禁用这个选项,以保持与现有 Red Hat Single Sign-On 实例的向后兼容性。
启用串行数十六进制表示
以十六进制表示 序列号。设置了 sign 位的序列号必须为 1,必须留使用 00 八进制数。例如,根据 RFC5280,带有十进制值 161 或十六进制的 a1 的序列号被编码为 00a1。如需了解更多详细信息,请参阅 RFC5280, appendix-B
正则表达式
用作提取证书身份的过滤器的正则表达式。表达式必须包含单个组。
用户映射方法
定义与现有用户身份匹配的方法。根据用户名或电子邮件 搜索现有用户的用户名或电子邮件.自定义属性映射程序 会搜索具有与证书身份匹配的自定义属性的现有用户。自定义属性的名称是可配置的。
名称 user 属性
其值与证书身份匹配的自定义属性。如果属性映射与多个值相关,请使用多个自定义属性,例如:'Certificate Serial Number 和 IssuerDN'。
启用 CRL 检查
使用 Certificate Revocation List 检查证书的吊销状态。列表的位置在 CRL 文件路径 属性中定义。
启用 CRL Distribution Point 来检查证书撤销状态
使用 CDP 检查证书撤销状态。大多数 PKI 颁发机构在证书中包含 CDP。
CRL 文件路径
包含 CRL 列表的文件路径。如果启用了 CRL Checking Enabled 选项,则该值必须是到有效文件的路径。
启用 OCSP 检查
使用在线证书状态协议检查证书撤销状态。
OCSP Fail-Open Behavior
默认情况下,OCSP 检查必须返回正响应,以便继续成功验证。有时,这个检查可能会排除:例如,OCSP 服务器无法访问,超载,或者客户端证书可能不包含 OCSP 响应器 URI。当启用此设置时,只有在 OCSP 响应程序收到明确的负响应并且证书绝对被撤销时,才会拒绝身份验证。如果一个有效的 OCSP 响应不是无效的验证尝试,则会接受验证尝试。
OCSP Responder URI
覆盖证书中的 OCSP 响应者 URI 值。
验证密钥使用
验证是否已设置证书的密钥扩展位。例如:"数字签名,KeyEncipherment"验证是否设置了 KeyUsage 扩展中的位 0 和 2。保留此参数为空以禁用 Key Usage 验证。如需更多信息,请参阅 RFC5280, Section-4.2.1.3。当键使用不匹配时,红帽单点登录会引发错误。
验证扩展密钥使用
验证扩展密钥使用扩展中定义的一个或多个目的。如需更多信息,请参阅 RFC5280, Section-4.2.1.12。将此参数设置为空以禁用扩展密钥使用验证。当被发出 CA 和密钥使用扩展不匹配时,Red Hat Single Sign-On 会引发一个错误。
验证证书策略
验证证书策略扩展中定义的一个或多个策略 OID。请参阅 RFC5280、Section-4.2.1.4。将参数留空,以禁用证书策略验证。使用逗号分隔多个策略。
证书策略验证模式
当在 Validate Certificate Policy 设置中指定了多个策略时,它决定匹配是否应检查所有请求的策略,或者一个匹配度足以成功身份验证。默认值为 All,表示所有请求的策略都应存在于客户端证书中。
绕过身份确认
如果启用,X.509 客户端证书身份验证不会提示用户确认证书身份。红帽单点登录在成功身份验证后对用户进行签名。
Revalidate 客户端证书
如果设置,客户端证书信任链总是使用配置的信任存储中存在的证书在应用程序级别进行验证。如果底层 Web 服务器没有强制验证客户端证书链验证,例如,它位于非值负载均衡器或反向代理后面,或者当允许 CA 的数量太大时,对于 mutual SSL 协商(大多数浏览器上限的 SSL 协商大小上限为 32767 字节,它对应于 200 公告的 CA)。默认情况下,这个选项是 off。

8.5.5. 在直接授予流中添加 X.509 客户端证书验证

  1. 在菜单中,单击 Authentication
  2. 点 "Direct Grant" 流。
  3. 单击 Copy,以制作"Direct Grant"流的副本。
  4. 输入副本的名称。
  5. 确定
  6. 单击"用户名验证"的 Actions 链接,再单击删除
  7. Delete
  8. 单击"密码"的 Actions 链接,再单击删除
  9. Delete
  10. 单击 Add execution
  11. 点 "X509/Validate Username"。
  12. Save

    X509 直接授权执行

    X509 Direct Grant Execution

  13. 按照 x509 浏览器流部分中介绍的步骤来设置 x509 身份验证配置。
  14. 单击 Bindings 选项卡。
  15. 点击 Direct Grant Flow 下拉列表。
  16. 点新创建的 "x509 Direct Grant" 流。
  17. Save

    X509 直接授权流绑定

    X509 Direct Grant Flow Bindings

8.5.6. 客户端证书查找

当红帽单点登录服务器收到直接 HTTP 请求时,JBoss EAP undertow 子系统建立 SSL 握手并提取客户端证书。JBoss EAP 将客户端证书保存到 HTTP 请求的 javax.servlet.request.X509Certificate 属性,如 servlet 规范中所述。Red Hat Single Sign-On X509 验证器可以从此属性中查找证书。

但是,当 Red Hat Single Sign-On 服务器监听负载均衡器或反向代理后面的 HTTP 请求时,代理服务器可以提取客户端证书并建立相互 SSL 连接。反向代理通常将经过身份验证的客户端证书放在底层请求的 HTTP 标头中。代理将请求转发到后端 Red Hat Single Sign-On 服务器。在这种情况下,Red Hat Single Sign-On 必须从 HTTP 标头而不是 HTTP 请求的属性中查找 X.509 证书链。

如果 Red Hat Single Sign-On 位于反向代理后,您通常需要在 RHSSO_HOME/standalone/configuration/standalone.xml 中配置 x509cert-lookup SPI 的替代供应商。当 默认 供应商查找 HTTP 标头证书时,存在两个其他内置供应商: haproxyapache

8.5.6.1. HAProxy 证书查找供应商

当 Red Hat Single Sign-On 服务器位于 HAProxy 反向代理后面时,您可以使用此供应商。为您的服务器使用以下配置:

<spi name="x509cert-lookup">
    <default-provider>haproxy</default-provider>
    <provider name="haproxy" enabled="true">
        <properties>
            <property name="sslClientCert" value="SSL_CLIENT_CERT"/>
            <property name="sslCertChainPrefix" value="CERT_CHAIN"/>
            <property name="certificateChainLength" value="10"/>
        </properties>
    </provider>
</spi>

在本示例配置中,客户端证书是从 HTTP 标头、SSL_CLIENT_CERT 以及其链中其他证书中查找,如 CERT_CHAIN_0CERT_CHAIN_9。属性 certificateChainLength 是链的最大长度,因此最后一个属性是 CERT_CHAIN_9

有关为客户端证书和客户端证书链配置 HTTP 标头的详细信息,请参阅 HAProxy 文档。

8.5.6.2. Apache 证书查找供应商

当 Red Hat Single Sign-On 服务器位于 Apache 反向代理后面时,您可以使用此供应商。为您的服务器使用以下配置:

<spi name="x509cert-lookup">
    <default-provider>apache</default-provider>
    <provider name="apache" enabled="true">
        <properties>
            <property name="sslClientCert" value="SSL_CLIENT_CERT"/>
            <property name="sslCertChainPrefix" value="CERT_CHAIN"/>
            <property name="certificateChainLength" value="10"/>
        </properties>
    </provider>
</spi>

此配置与 haproxy 供应商相同。如需了解有关配置客户端证书和客户端证书链的 HTTP 标头的详细信息,请参阅 mod_sslmod_headers 上的 Apache 文档。

8.5.6.3. NGINX 证书查找供应商

当 Red Hat Single Sign-On 服务器位于 NGINX 反向代理后面时,您可以使用此供应商。为您的服务器使用以下配置:

<spi name="x509cert-lookup">
    <default-provider>nginx</default-provider>
    <provider name="nginx" enabled="true">
        <properties>
            <property name="sslClientCert" value="ssl-client-cert"/>
            <property name="sslCertChainPrefix" value="USELESS"/>
            <property name="certificateChainLength" value="2"/>
        </properties>
    </provider>
</spi>
注意

NGINX SSL/TLS 模块 不会公开客户端证书链。Red Hat Single Sign-On 的 NGINX 证书查找提供程序通过使用 Keycloak 信任存储来重建该提供程序。使用 keytool CLI 及所有 root 和中间 CA 用于重建客户端证书链,以此填充 Red Hat Single Sign-On 信任存储。

有关为客户端证书配置 HTTP 标头的详细信息,请参阅 NGINX 文档。

NGINX 配置文件示例:

 ...
 server {
    ...
    ssl_client_certificate                  trusted-ca-list-for-client-auth.pem;
    ssl_verify_client                       optional_no_ca;
    ssl_verify_depth                        2;
    ...
    location / {
      ...
      proxy_set_header ssl-client-cert        $ssl_client_escaped_cert;
      ...
    }
    ...
}
注意

trusted-ca-list-for-client-auth.pem 中的所有证书都必须添加到 Keycloak 信任存储中

8.5.6.4. 其他反向代理实现

Red Hat Single Sign-On 没有可用于其他反向代理实现的内置支持。但是,您可以使其他反向代理的行为与 apachehaproxy 类似。如果没有这些工作,请创建您的 org.keycloak.services.x509.X509ClientCertificateLookupFactoryorg.keycloak.services.x509.X509ClientCertificateLookup 提供程序。有关如何添加您的供应商的详细信息,请参阅 服务器开发人员指南

8.5.7. 故障排除

转储 HTTP 标头
若要查看反向代理向 Keycloak 发送的内容,启用 RequestDumpingHandler Undertow 过滤器并查阅 server.log 文件。
在 logging 子系统下启用 TRACE 日志记录
...
    <profile>
        <subsystem xmlns="urn:jboss:domain:logging:8.0">
...
            <logger category="org.keycloak.authentication.authenticators.x509">
                <level name="TRACE"/>
            </logger>
            <logger category="org.keycloak.services.x509">
                <level name="TRACE"/>
            </logger>
警告

不要在生产环境中使用 RequestDumpingHandler 或 TRACE 日志记录。

使用 X.509 直接授予身份验证

要执行这个身份验证,您需要以下内容:

  • root CA 和中间 CA
  • 用户签名的证书请求,使用 root CA/intermediate CA 签名

您可以使用以下模板,使用 Resource Owner Password Credentials Grant 来请求令牌:

$ LOC=<install-dir>/intermediate1/user-certificate

$ curl --insecure https://localhost:8443/auth/realms/X509_demo/protocol/openid-connect/token --data "grant_type=password" -E $LOC/user1.crt --key $LOC/user1.key --cacert $LOC/intermediate-ca-chain.crt -d client_id=account -d client_secret=BNm5AQPJGEtbayIAoiKUetr0lkXKSlF4 | jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 2097 100 2013 100 84 25481 1063 -::- -::- -::- 26544
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ1OUNpN0tzUjBIOEFCQXEtQ1Z4SEFDSUo1M1hNYWVhclJrYkw4cFd1VW4wIn0.eyJleHAiOjE2Njc4MzA5NjAsImlhdCI6MTY2NzgzMDY2MCwianRpIjoiNDU5YzE2OGMtODU3ZS00OWRjLTgxYjItZjVhM2M3M2MwODMzIiwiaXNzIjoiaHR0cHM6Ly9sb2NhbGhvc3Q6ODQ0My9hdXRoL3JlYWxtcy9YNTA5X2RlbW8iLCJzdWIiOiIwODZiMTgyZC00MzdhLTQzZDItYTRmZS05ZGZmYTNmOTBiZDAiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJhY2NvdW50Iiwic2Vzc2lvbl9zdGF0ZSI6ImMwYjNiMTJjLTM5YmEtNGQ0Ni1iNDNlLTZkMTM0MGJmNTA5OCIsImFjciI6IjEiLCJyZXNvdXJjZV9hY2Nlc3MiOnsiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJwcm9maWxlIGVtYWlsIiwic2lkIjoiYzBiM2IxMmMtMzliYS00ZDQ2LWI0M2UtNmQxMzQwYmY1MDk4IiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJ1c2VyMSIsImVtYWlsIjoidXNlckByZWRoYXQuY29tIn0.CDtltEkmITloDpqU5alq4U1JopqEJVeoglT-wA43edQ_DfeWSgefL0BIrPlt1SKhFMOVitwyq_9XZvfiS5ZiObE33cDmhr6eohbUtDPibU2GuEIYP9WjlVpZDMaSKQVu5SwM91m6yei22PtH-ApPOBeG4Ru0xZtNXjwGQpuIJEi_H1rZdPY3I4U2lPuQo4Uono5gnF7re_nUvf90FJi0uaOOrsvUhUkj1xEwQ0Diy1oIymcbrDL0Ek7B30StBcjn-fe3-0GpLttLQju0OGTkwD7Eb0UWTKoWAwspMlgpf9NaIGj8rmBsz6eBlGIGWBN2Qg6v3PzbJ2NXKvq435f9Zg",
"expires_in": 300,
"refresh_expires_in": 1800,
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICIyMmFkZDdhMy0xN2RjLTQ5NmQtYTk4NS05YWZhNGZhODVhMTEifQ.eyJleHAiOjE2Njc4MzI0NjAsImlhdCI6MTY2NzgzMDY2MCwianRpIjoiZWU4MjJhMzYtMWEzMS00ZGEzLWIxMGEtNmY1ODkxYmI0MzlhIiwiaXNzIjoiaHR0cHM6Ly9sb2NhbGhvc3Q6ODQ0My9hdXRoL3JlYWxtcy9YNTA5X2RlbW8iLCJhdWQiOiJodHRwczovL2xvY2FsaG9zdDo4NDQzL2F1dGgvcmVhbG1zL1g1MDlfZGVtbyIsInN1YiI6IjA4NmIxODJkLTQzN2EtNDNkMi1hNGZlLTlkZmZhM2Y5MGJkMCIsInR5cCI6IlJlZnJlc2giLCJhenAiOiJhY2NvdW50Iiwic2Vzc2lvbl9zdGF0ZSI6ImMwYjNiMTJjLTM5YmEtNGQ0Ni1iNDNlLTZkMTM0MGJmNTA5OCIsInNjb3BlIjoicHJvZmlsZSBlbWFpbCIsInNpZCI6ImMwYjNiMTJjLTM5YmEtNGQ0Ni1iNDNlLTZkMTM0MGJmNTA5OCJ9.MubgR9rvyrmSOcaq5ce-qVTPenVQye1KsEHJr7nh9-A",
"token_type": "Bearer",
"not-before-policy": 0,
"session_state": "c0b3b12c-39ba-4d46-b43e-6d1340bf5098",
"scope": "profile email"
}
[host][:port]
远程 Red Hat Single Sign-On 服务器的主机和端口号。
user_cert.crt
用户的公钥。
user_cert.key
用户的私钥。这个密钥会验证公钥是否没有被伪造。私钥指向与公钥相同的哈希。
CLIENT_ID
客户端 ID。
CLIENT_SECRET
对于机密客户端,客户端机密。
Red Hat logoGithubRedditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

© 2024 Red Hat, Inc.