Tuesday, 26 March 2024

How to Setup Liberty to Use Certificate-Based Authentication

 

How to Setup Liberty to Use Certificate-Based Authentication


Summary

Any JEE web application running on WebSphere Application Server Liberty can use SSL certificate authentication by configuring Liberty to use CLIENT-CERT authentication. These same steps are typically applicable to those wanting to enable authentication for smart cards (CAC/PIV) because the smart card acts as a keystore on the client side, providing certificates to authenticate with servers such as Liberty.

High-Level Steps

1. Configure Web Application with client certificate authentication.
2. Configure Liberty SSL configuration with client authentication.
3. Configure Liberty LDAP Security Configuration with certificate filter.
4. Configure the Browser to present the certificate.
5. How to enable traces and verify the client certificate authentication.

Objective

This document contains the overall step by step instructions for setting this up securely within Liberty using a sample application called libertyDefaultApplicationCLIENT-CERT.ear

Steps

This document contains the necessary steps to instantiate a secure connection between the Browser (Client) and Liberty Server. Please see the following picture.
image-20200204194658-1
Note: If you have webserver then you need to configure 2 way SSL on the  IBM HTTP server ( Webserver). You don't need to enable 2 way SSL clientAuthentication="true" As the certificate information is submitted to the liberty server via $WCC header. On Liberty configuration you need to define trustedSensitiveHeaderOrigin in server.xml file with <httpDispatcher trustedSensitiveHeaderOrigin="*"/> For more detail check the following infocenter link  https://www.ibm.com/support/knowledgecenter/SSEQTP_liberty/com.ibm.websphere.liberty.autogen.base.doc/ae/rwlp_config_httpDispatcher.html#trustedSensitiveHeaderOrigin
Please see the following request flow picture.
image-20200204195300-2


1. Configure Web Application with client certificate authentication


Per the J2EE specification, web applications (.wars) must contain a web.xml deployment descriptor file in which the programmer can specify the application's authentication mechanism.
The auth-method element within web.xml is used to specify the authentication mechanism. To enable SSL client authentication, the auth-method must be set to CLIENT-CERT.
Ensure that the deployment descriptor for your web application specifies client certificate authentication as the authentication method to use.
Check that the deployment descriptor includes the following element:
<login-config>
    <auth-method>CLIENT-CERT</auth-method>
</login-config>
Note: You need to work with your Application Developer to make these changes in the deployment descriptor for your web application
I am providing a sample application called libertyDefaultApplicationCLIENT-CERT.ear.

Click here to download the SAMPLE application ==> libertyDefaultApplicationCLIENT-CERT.ear


Deploying libertyDefaultApplicationCLIENT-CERT in Liberty Server
Place this libertyDefaultApplicationCLIENT-CERT.ear under the dropins folder, ${server.config.dir}/dropins (that is, wlp/usr/servers/server_name/dropins). By default, the dropins directory is automatically monitored. If you drop an application into this directory, the application is automatically deployed on the server.
Example Screenshot
app

2. Configure Liberty SSL to support a two-way handshake.
 


Add the transportSecurity-1.0 Liberty feature in your server.xml file. The transportSecurity-1.0 feature supersedes the ssl-1.0 feature.  This feature enables support for Secure Sockets Layer (SSL) connections
<feature>transportSecurity-1.0</feature>
Configure your server to enable SSL client authentication by adding the following lines to the server.xml file:
When you specify clientAuthenticationSupported in a Liberty ssl configuration element, then when that configuration element is used for an inbound connection, Liberty will request that the client sends a certificate at the transport layer (SSL).
 If you specify clientAuthentication="true", the server requests that a client sends a certificate. However, if the client does not have a certificate, or the certificate is not trusted by the server, the handshake does not succeed.
 
 
      <!-- default SSL configuration is defaultSSLSettings -->      
    <sslDefault sslRef="defaultSSLSettings" />
    <ssl id="defaultSSLSettings" keyStoreRef="defaultKeyStore" sslProtocol="SSL_TLSv2" trustStoreRef="defaultTrustStore"
clientAuthentication="true"/>
 <keyStore id="defaultKeyStore" location="key.jks" type="JKS" password="defaultPWD" />
 <keyStore id="defaultTrustStore" location="key.jks" type="JKS" password="defaultPWD" />
Note: defaultKeyStore is located under  wlp/ usr/servers/server/liberty/servers/servername/resources/security/key.jks
defaultTrustStore is located under wlp/ usr/servers/server/liberty/servers/servername/resources/security/key.jks
Make sure the server trusts any client certificates that are used by adding the signer(s) of your client certificate(s) to the trustStore being used, e.g. key.jks (defaultTrustStore).

You can use the Java keytool command to import the certificate into the trustStore. The keytool utility is located under java_home/jre/bin. Here's an example command showing how to import a signer certificate into a keystore:

keytool -keystore wlp/usr/servers/server/liberty/servers/servername/resources/security/key.jks -storepass defaultPWD -importcert -alias ClientCert -file /temp/clientcertificate.cer

And here is an example command which can be used to verify that the certificate has been successfully added.

keytool -list -v -keystore wlp/usr/servers/server/liberty/servers/servername/resources/security/key.jks -storepass defaultPWD

keytool

Note: Any signer for the client certificate can be added; if the certificate chain contains one or more intermediate signers, adding any of those or adding the root signer will allow the server to send a workable CertificateRequest to the client during the handshake process.

3. Configure a certificate filter for the Liberty user registry (LDAP)


Add the ldapRegistry-3.0 Liberty feature to the server.xml file. This will enable the LDAP User Registry feature

<feature>ldapRegistry-3.0</feature>

In order to configure an LDAP in Liberty with a certificate filter, you need the following information.
    
1.    Host name of the Active Directory server.

2.    LDAP port of Active Directory Server (typically non-ssl port 389).

3.    Bind DN with which WAS will connect in order to query entries.

4.    Bind password corresponding to DN.

5.    The search base under which all users exist.

6.    Configuring the LDAP certificate mapping filter.

The certificate filter tells the Liberty server which element(s) from the certificate should be used to locate the user in the LDAP. Liberty will form an LDAP search query based on the design of the certificate filter configuration.

    certificateMapMode="CERTIFICATE_FILTER"
    certificateFilter="sAMAccountName=${SubjectCN}"

Here is Sample Screenshot of the server.xml


server.xml

In this example, the DNs on the client certificate do not exactly match the DNs of the users in the LDAP, so we must use CERTIFICATE_FILTER mode, and specify a Certificate filter.  The filter is used to map attributes in the client certificate to entries in the LDAP registry. If the DNs on your client certificates match the LDAP user DNs exactly, then instead of using CERTIFICATE_FILTER mode you should use EXACT_DN mode.

The values for these the certificateMapMode and certificateFilter are highly dependent on your certificate and user registry settings.

For example, let's say that your Liberty server is currently configured to allow a user with the userid "RAMARIKA" (full LDAP DN: CN=RAMARIKA,DC=L2User,DC=Austin,DC=IBM,DC=COM) from an Active Directory LDAP to log-in. This user entry on the LDAP has an attribute called sAMAccountName with value RAMARIKA which enables the LDAP login. The "RAMARIKA" user would like to log-in with a certificate with the following subject: "CN=RAMARIKA,OU=TEST,O=IBM,C=US". You could configure Liberty to use the 'Common Name' entry in the certificate as the user ID (sAMAccountName attribute in this example) of the logged in user by using the  CERTIFICATE_FILTER mode for the Certificate mapping setting and the  "sAMAccountName=${SubjectCN}" value for the Certificate filter setting.  

For more details please refer to the certificateFilter documentation here:


4. Configure the Browser to present the certificate


For a smart card, the following steps may not be necessary. Similarly, if your end-users already have client certificates installed on their workstation these steps may not be necessary. This is an example of how to install a client certificate onto a Microsoft Windows client machine.

    From the Internet Explorer menu bar, select Tools > Internet Options > Content > Certificates button > Personal tab.  Click Import.
IE
You will see the Certificate Wizard pop up, click Next. 

ie-import Browse to your keystore file that has the private key or personal certificate, for example, a .p12 or PFX file
Import Cert

Enter the password for the private key
Enter password
  Browse to the Personal folder (should be the default). Click Next
select personal cert

Click Finish to finalize the import
finish
checkpersonal cert

Test the client certificate authentication using the sample application's "snoop" servlet. When you access the application you should get prompt to select the certificate.
The client (browser) builds a list of the end-user’s certificates, from all that are available, that have been signed by any of the server’s list of trusted parties, and the end user must select a certificate from the list. Typically, the creation of a client-side certificate involves a Certificate Authority. However, for the purpose of this section, we create a self-signed personal certificate in the following browser certificate.
desk


To avoid this message the Liberty server’s certificate must be signed by a trusted signer. An organization can purchase a certificate from one of the many commercially known Certificate Authorities (who are typically trusted by browsers). Some organizations have their own in-house Certificate Authorities or External Certificate Authority such as Verisign, entrust, GoDaddy.etc, and the ability to control the list of trusted signers on all of the organization’s desktops. browser error
Once it is successfully passed you will see the snoop page as follows snoop
The snoop servlet shows various request related information. Scroll down to the HTTPS Information section . You can see that our certificate data shows client certificate chain information.
cert in header

5. How to enable traces and verify the client certificate authentication.


Use the following trace string in the Liberty server server.xml
SSLChannel=all:com.ibm.ws.ssl.*=all:com.ibm.websphere.ssl=all:com.ibm.wsspi.ssl.*=all:com.ibm.ws.security.*=all:com.ibm.ws.webcontainer.security.*=all
Trace string
Verify that your tracing is working as intended
    Stop the Liberty Server
    Delete any existing logs files found under the logs directory:
    <LIBERTY_HOME>/usr/servers/<serverName>/logs
    Restart the Liberty Server and review the logs to confirm that they are recent.
How to  verify certificate base authentication from traces

Once you attempt to access the snoop application, Liberty checks the application web.xml for login method. In this case, we want the login method to be CLIENT_CERT
[4/10/19 11:27:00:315 CDT] 00000033 WebAppSecurit >  performInitialChecks Entry  
                                 com.ibm.ws.webcontainer.security.WebRequestImpl@489e7399
                                 /snoop
[4/10/19 11:27:00:325 CDT] 00000033 LoginConfigur >  getAuthenticationMethod Entry
[4/10/19 11:27:00:325 CDT] 00000033 LoginConfigur <  getAuthenticationMethod Exit  
                                 CLIENT_CERT


During authenticateRequest you should see the X509 certificate being passed in from the client as follows

[4/10/19 11:27:00:375 CDT] 00000033 Authenticatio >  authenticate Entry  
                                 system.WEB_INBOUND
                                 {HTTP_SERVLET_RESPONSE=com.ibm.ws.webcontainer.srt.SRTServletResponse@8c4f7f4a, HTTP_SERVLET_REQUEST=com.ibm.ws.webcontainer.srt.SRTServletRequest@f837784f, CERTCHAIN=[Ljava.security.cert.X509Certificate;@ae5f57d5}
                                 null

    
authenticateRequest gets the certificate chain and hands over to the handleUserLogin method   
                                 
[4/10/19 11:27:00:380 CDT] 00000033 WSAuthenticat >  get Entry  
                                 CERTCHAIN
[4/10/19 11:27:00:380 CDT] 00000033 WSAuthenticat >  isSensitive Entry  
                                 CERTCHAIN
[4/10/19 11:27:00:380 CDT] 00000033 WSAuthenticat <  isSensitive Exit  
                                 false
[4/10/19 11:27:00:380 CDT] 00000033 WSAuthenticat <  get Exit  
                                 <sensitive [Ljava.security.cert.X509Certificate;@ae5f57d5>
                                  [4/10/19 11:27:00:390 CDT] 00000033 CertificateLo >  handleUserLogin Entry  
                                 [
[
  Version: V3
  Subject: CN=RAMARIKA, OU=TEST, O=IBM, C=US
  Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.1
 
 
 the LDAP user registry retrieves credential information and maps the credential for the certificate.
 
 [4/10/19 11:27:00:390 CDT] 00000033 UserRegistryS >  getUserRegistry Entry
[4/10/19 11:27:00:390 CDT] 00000033 UserRegistryS >  determineActiveUserRegistry Entry  
                                 true
[4/10/19 11:27:00:390 CDT] 00000033 UserRegistryS <  determineActiveUserRegistry Exit  
                                 com.ibm.ws.security.wim.registry.WIMUserRegistry@21bd92c5
                                 
                                 
more certificate to LDAP user registry mapping...

[4/10/19 11:27:00:390 CDT] 00000033 WIMUserRegist >  mapCertificate Entry  
                                 [
[
  Version: V3
  Subject: CN=RAMARIKA, OU=TEST, O=IBM, C=US
  Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11    
 
 
  [4/10/19 11:27:00:445 CDT] 00000033 LdapAdapter   >  mapCertificate Entry  
                                 [
[
  Version: V3
  Subject: CN=RAMARIKA, OU=TEST, O=IBM, C=US
  Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11
 
Liberty makes a call to the LDAP using the certificateFilter configured under server.xml According to our example filter in server.xml the user identity is the common name (CN) from the distinguished name (DN) of the certificate.
[4/10/19 11:27:00:445 CDT] 00000033 LdapConfigMan >  getCertificateLDAPFilter Entry  
                                 [
[
  Version: V3
  Subject: CN=RAMARIKA, OU=TEST, O=IBM, C=US
 
 [4/10/19 11:27:00:445 CDT] 00000033 LdapHelper    >  getDNSubField Entry  
                                 CN
                                 CN=RAMARIKA,OU=TEST,O=IBM,C=US
[4/10/19 11:27:00:455 CDT] 00000033 LdapHelper    <  getDNSubField Exit  
                                 RAMARIKA
[4/10/19 11:27:00:460 CDT] 00000033 LdapConfigMan <  getCertificateLDAPFilter Exit  
                                 sAMAccountName=RAMARIKA
 
 Liberty then does the actual LDAP lookup for the user
 
 
[4/10/19 11:27:00:460 CDT] 00000033 LdapConnectio >  search Entry  
                                 DC=AUSTIN,DC=IBM,DC=COM
                                 sAMAccountName=RAMARIKA
                                 null
                                 javax.naming.directory.SearchControls@1ff04135
                                 null

After the user is found in the LDAP, the LDAP caches are updated and we can see details about the user entry from the LDAP result:

[4/10/19 11:27:00:485 CDT] 00000033 LdapConnectio >  updateAttributesCache Entry  
                                 CN=ramarika,CN=Users,DC=AUSTIN,DC=IBM,DC=COM
                                 {objectguid=objectGUID: [B@564a6e87, objectclass=objectClass: top, person, organizationalPerson, user}
                                 null
                                 objectguid
                                 objectClass                                  [4/10/19 11:27:00:525 CDT] 00000033 VMMService    >  get Entry  
                                 com.ibm.wsspi.security.wim.model.Root=
[contexts={com.ibm.wsspi.security.wim.model.Context=
[key=isURBridgeResult
value=false
]}
entities={com.ibm.wsspi.security.wim.model.Entity=
[IdentifierType= {
    uniqueName=CN=ramarika,CN=Users,DC=AUSTIN,DC=IBM,DC=COM                          
After the user is pulled from the LDAP and the initial login completes, Liberty will create an LTPA token cookie which can be used by the client for subsequent authentications
[4/10/19 11:27:00:707 CDT] 00000033 LTPAToken2Fac >  createToken Entry  
                                 {unique_id=user:myldap.austin.ibm.com:389/CN=ramarika,CN=Users,DC=AUSTIN,DC=IBM,DC=COM}
[4/10/19 11:27:01:095 CDT] 00000033 SSOCookieHelp >  createCookie Entry  
                                 com.ibm.ws.webcontainer.srt.SRTServletRequest@f837784f
                                 JqZo+9BVmugnlGuv0yWP9pTxk5ozMwkIArSI5MYsA0plLyrGALvf3KgBnPJgqZHfcB8X+iJ8JjFoeKPr/FkMAsAe7/zUDGoP8qLxEOqVbwPtWVcajzBinDmwzTcPR9xrGFefbTG0/aylR9ui/TEknmXcdc2GcmCg0EzxgP+6OEg1Y1MkPda26Q3DOK9hZR8YfAWXiLF/RPb3TM3bXbGOZxblZjZNVj4RydB50y8vq9IThTBiYsK4+HY/7xSstsmevMUay+oXj53RLteJXjNKizvBXLx+IT1c46H8YnEPeX089tAkE//Pa1xSPK5jkrnHN4a3F9d        
         ============== Thank you for using this document======================== 
Reference/Source link : https://www.ibm.com/support/pages/how-setup-liberty-use-certificate-based-authentication