7.5.2. 将 CLIENT-CERT SSL 身份验证迁移到 Elytron
要启用 CLIENT-CERT SSL 身份验证,请在身份验证元素中添加 truststore 元素。
<security-realm name="ManagementRealm">
<server-identities>
<ssl>
<keystore path="server.keystore" relative-to="jboss.server.config.dir" keystore-password="KEYSTORE_PASSWORD" alias="server" key-password="key_password" />
</ssl>
</server-identities>
<authentication>
<truststore path="server.truststore" relative-to="jboss.server.config.dir" keystore-password="TRUSTSTORE_PASSWORD" />
<local default-user="$local"/>
<properties path="mgmt-users.properties" relative-to="jboss.server.config.dir"/>
</authentication>
</security-realm>
通过此配置,如果未发生 CLIENT-CERT 身份验证,客户端可以回退为使用本地机制或 用户名/密码 身份验证机制。要使基于 CLIENT-CERT 的身份验证强制要求,请删除 本地 和 属性 元素。
可以通过 两种方式使用传统的信任存储 :
传统 信任存储 仅包含 CA
按照以下步骤配置服务器,以防止没有有效证书和私钥的用户使用 Elytron 访问服务器。
在
elytron 子系统中创建密钥存储,以指定密钥存储的位置以及加密时使用的密码。此命令假定密钥存储是使用 keytool 命令生成的,其类型为JKS。/subsystem=elytron/key-store=LocalhostKeyStore:add(path=server.keystore,relative-to=jboss.server.config.dir,credential-reference={clear-text="keystore_password"},type=JKS)在
elytron 子系统中创建密钥存储,以指定信任存储的位置以及加密时使用的密码。此命令假定密钥存储是使用 keytool 命令生成的,其类型为JKS。/subsystem=elytron/key-store=TrustStore:add(path=server.truststore,relative-to=jboss.server.config.dir,credential-reference={clear-text="truststore_password"},type=JKS)在
elytron子系统中创建key-manager,以指定之前定义的LocalhostKeyStore密钥存储、别名和密钥的密码。/subsystem=elytron/key-manager=LocalhostKeyManager:add(key-store=LocalhostKeyStore,alias-filter=server,credential-reference={clear-text="key_password"})在
elytron子系统中创建trust-manager,以指定之前创建的truststore的密钥存储。/subsystem=elytron/trust-manager=TrustManager:add(key-store=TrustStore)在
elytron子系统中创建server-ssl-context,它将引用之前定义的key-manager,设置trust-manager属性并启用客户端身份验证。/subsystem=elytron/server-ssl-context=LocalhostSslContext:add(key-manager=LocalhostKeyManager,trust-manager=TrustManager,need-client-auth=true)将
https-listener从传统security-realm切换到新创建的 Elytronssl-context。batch /subsystem=undertow/server=default-server/https-listener=https:undefine-attribute(name=security-realm) /subsystem=undertow/server=default-server/https-listener=https:write-attribute(name=ssl-context,value=LocalhostSslContext) run-batch重新加载服务器:
reload
这会在服务器配置文件中产生以下 elytron 子系统配置:
<subsystem xmlns="urn:wildfly:elytron:4.0"...>
...
<tls>
<key-stores>
<key-store name="LocalhostKeyStore">
<credential-reference clear-text="keystore_password"/>
<implementation type="JKS"/>
<file path="server.keystore" relative-to="jboss.server.config.dir"/>
</key-store>
<key-store name="TrustStore">
<credential-reference clear-text="truststore_password"/>
<implementation type="JKS"/>
<file path="server.truststore" relative-to="jboss.server.config.dir"/>
</key-store>
</key-stores>
<key-managers>
<key-manager name="LocalhostKeyManager" key-store="LocalhostKeyStore" alias-filter="server">
<credential-reference clear-text="key_password"/>
</key-manager>
</key-managers>
<trust-managers>
<trust-manager name="TrustManager" key-store="TrustStore"/>
</trust-managers>
<server-ssl-contexts>
<server-ssl-context name="LocalhostSslContext" need-client-auth="true" key-manager="LocalhostKeyManager" trust-manager="TrustManager"/>
</server-ssl-contexts>
</tls>
</subsystem>
这会在服务器配置文件中产生以下 undertow 子系统配置:
<subsystem xmlns="urn:jboss:domain:undertow:10.0">
...
<https-listener name="https" socket-binding="https" ssl-context="LocalhostSslContext" enable-http2="true"/>
...
</subsystem>
域和域
为了允许使用预定义的 Elytron ManagementDomain 安全域和 ManagementRealm 安全 域,用户存储在标准属性文件中。
<security-domains>
<security-domain name="ManagementDomain" default-realm="ManagementRealm" permission-mapper="default-permission-mapper">
<realm name="ManagementRealm" role-decoder="groups-to-roles"/>
<realm name="local"/>
</security-domain>
</security-domains>
<security-realms>
<properties-realm name="ManagementRealm">
<users-properties path="mgmt-users.properties" relative-to="jboss.server.config.dir" digest-realm-name="ManagementRealm"/>
<groups-properties path="mgmt-groups.properties" relative-to="jboss.server.config.dir"/>
</properties-realm>
</security-realms>
安全域在两种情形中使用:
- 证书身份验证失败时,安全域用于密码回退案例。
- 为密码和证书完成授权后,域提供单个用户的角色。
因此,对于任何客户端证书,安全域中都必须存在用户。
主体解码器
使用证书身份验证并且安全域接受用户名来解析身份时,必须有定义的方式从客户端证书获取 用户名。
在这种情况下,CN 属性用于证书主题。
/subsystem=elytron/x500-attribute-principal-decoder=x500-decoder:add(attribute-name=CN)
HTTP 身份验证事实
对于 HTTP 连接,使用先前定义的资源定义 HTTP 身份验证工厂。它将配置为支持 CLIENT_CERT 和 DIGEST 身份验证。
由于属性域仅验证密码并且无法验证客户端证书,您需要首先添加配置机制工厂。这将禁用针对安全域的证书验证。
/subsystem=elytron/configurable-http-server-mechanism-factory=configured-cert:add(http-server-mechanism-factory=global, properties={org.wildfly.security.http.skip-certificate-verification=true})
HTTP 身份验证可以创建为:
./subsystem=elytron/http-authentication-factory=client-cert-digest:add(http-server-mechanism-factory=configured-cert,security-domain=ManagementDomain,mechanism-configurations=[{mechanism-name=CLIENT_CERT,pre-realm-principal-transformer=x500-decoder},{mechanism-name=DIGEST, mechanism-realm-configurations=[{realm-name=ManagementRealm}]}])
以上命令会产生:
<subsystem xmlns="urn:wildfly:elytron:4.0" final-providers="combined-providers" disallowed-providers="OracleUcrypto">
...
<http>
...
<http-authentication-factory name="client-cert-digest" http-server-mechanism-factory="configured-cert" security-domain="ManagementDomain">
<mechanism-configuration>
<mechanism mechanism-name="CLIENT_CERT" pre-realm-principal-transformer="x500-decoder"/>
<mechanism mechanism-name="DIGEST">
<mechanism-realm realm-name="ManagementRealm"/>
</mechanism>
</mechanism-configuration>
</http-authentication-factory>
...
<configurable-http-server-mechanism-factory name="configured-cert" http-server-mechanism-factory="configured-cert">
<properties>
<property name="org.wildfly.security.http.skip-certificate-verification" value="true"/>
</properties>
</configurable-http-server-mechanism-factory>
...
</http>
...
</subsystem>