How to configure CLIENT-CERT authentication mechanism using Elytron ?
Environment
- Red Hat JBoss Enterprise Application Platform (EAP)
- 8.x
- 7.1+
Issue
- How to set up
CLIENT-CERTauthentication in EAP 7.1 using Elytron ? - How to enable
CLIENT-CERTauthentication mechanism for an application when EAP is hosted behind proxy/lb ?
Resolution
In order to configure CLIENT_CERT authentictaion it is required to first set up certificate-based authentication by configuring two-way SSL using Elytron.
1 . Configure a key-store-realm with a truststore that contains the client's certificate.
- CLI
/subsystem=elytron/key-store-realm=ksRealm:add(key-store=twoWayTS)
- XML
<key-store-realm name="ksRealm" key-store="twoWayTS"/>
Here the authentication process uses the same certificate presented by the client during the two-way SSL handshake.
2 . Create a x500-attribute-principal-decoder to decode the principal obtaibned from the certificate.
- CLI
/subsystem=elytron/x500-attribute-principal-decoder=CNDecoder:add(attribute-name="CN",maximum-segments=1)
- XML
<x500-attribute-principal-decoder name="CNDecoder" attribute-name="CN" maximum-segments="1"/>
The below example will decode the principal based on the first CN value. The decoded principal MUST be the alias value set in the server's truststore for the client's certificate.
3 . Add a constant-role-mapper to assign roles to a principal from ksRealm but other approaches may also be used.
- CLI
/subsystem=elytron/constant-role-mapper=constantClientCertRole:add(roles=[Admin,Guest])
- XML
<constant-role-mapper name="constantClientCertRole">
<role name="Admin"/>
<role name="Guest"/>
</constant-role-mapper>
4 . Configure a security-domain using above configured key-store-realm, principal-decoder and role-mapper.
- CLI
/subsystem=elytron/security-domain=exampleCertSD:add(realms=[{realm=ksRealm}],default-realm=ksRealm,permission-mapper=default-permission-mapper,principal-decoder=CNDecoder,role-mapper=constantClientCertRole)
- XML
<security-domain name="exampleCertSD" default-realm="ksRealm" permission-mapper="default-permission-mapper" principal-decoder="CNDecoder" role-mapper="constantClientCertRole">
<realm name="ksRealm"/>
</security-domain>
5 . Configure an http-authentication-factory using security-domain created in step 4.
- CLI
/subsystem=elytron/http-authentication-factory=exampleCertHttpAuth:add(http-server-mechanism-factory=global,security-domain=exampleCertSD,mechanism-configurations=[{mechanism-name=CLIENT_CERT,mechanism-realm-configurations=[{realm-name=exampleApplicationDomain}]}])
- XML
<http-authentication-factory name="exampleCertHttpAuth" http-server-mechanism-factory="global" security-domain="exampleCertSD">
<mechanism-configuration>
<mechanism mechanism-name="CLIENT_CERT">
<mechanism-realm realm-name="exampleApplicationDomain" pre-realm-principal-transformer="CNDecoder"/>
</mechanism>
</mechanism-configuration>
</http-authentication-factory>
6 . Configure an application-security-domain in the Undertow subsystem.
- CLI
/subsystem=undertow/application-security-domain=exampleApplicationDomain:add(http-authentication-factory=exampleCertHttpAuth)
- XML
<application-security-domains>
<application-security-domain name="exampleApplicationDomain" http-authentication-factory="exampleCertHttpAuth"/>
</application-security-domains>
7 . Update server-ssl-context to refer security domain created in step 4
- CLI
/subsystem=elytron/server-ssl-context=twoWaySSC:write-attribute(name=security-domain,value=exampleCertSD)
/subsystem=elytron/server-ssl-context=twoWaySSC:write-attribute(name=authentication-optional, value=true)
- XML
<server-ssl-contexts>
<server-ssl-context name="twoWaySSC" security-domain="exampleCertSD" protocols="TLSv1.2" need-client-auth="true" authentication-optional="true" key-manager="twoWayKM" trust-manager="twoWayTM" />
</server-ssl-contexts>
8 . Configure the application to use CLIENT-CERT authentication. An in the webapp.war/WEB-INF/web.xml file should look like the following.
<security-constraint>
<display-name>Constraint1</display-name>
<web-resource-collection>
<web-resource-name>application</web-resource-name>
<description/>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<description/>
<role-name>Admin</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>CLIENT-CERT</auth-method>
<realm-name>exampleApplicationDomain</realm-name>
</login-config>
<security-role>
<description/>
<role-name>Admin</role-name>
</security-role>
9 . Configure the application to use a security-domain (defined earlier). The in the webapp.war/WEB-INF/jboss-web.xml should look like the following.
<jboss-web>
<server-instance>default-server</server-instance>
<virtual-host>default-host</virtual-host>
<security-domain>exampleApplicationDomain</security-domain>
</jboss-web>
Note : When using CLIENT-CERT authentication behind mod_jk loadbalancer make following changes for x500-attribute-principal-decoder
<x500-attribute-principal-decoder name="CNDecoder" attribute-name="CN" maximum-segments="1" convert="true"/>
This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.