Prerequisites
Install and Configure JOSSO
You should first setup JOSSO for one of the supported platforms such as Tomcat and JBoss. Check the specific Setup HOW-TO corresponding to the platform where JOSSO is going to be installed.
Once you're done with the initial setup make sure that the JOSSO web application is accessible.
Availability of OpenSSL
In this tutorial we use the OpenSSL cryptographic toolkit for managing X.509 certificates.
OpenSSL is usually builtin in most Linux distributions (e.g. Redhat). If you are using Windows you can download a win32 binary distribution from here.
OpenSSL sources can be downloaded from here.
|
This tutorial assumes that there is at least a CA configured for OpenSSL. |
Introduction
This How-To will explain how to enable Strong Authentication in JOSSO using client certificates.
JOSSO's approach to single sign-on uses a single certificate rather than multiple passwords to authenticate a client to multiple servers. A certificate identifies an individual, a server, or some other entity. To authenticate a user to a server, a client digitally signs a randomly generated piece of data and sends both the certificate and the signed data across the network.For the purposes of this discussion, the digital signature associated with some data can be thought of as evidence provided by the client to the server. The server authenticates the user's identity on the strength of this evidence.
An XML Credential and Identity Store will be used, configured for fetching the user's certificate.
Tomcat will be used for handling SSL connections. Alternatively, Apache with mod_ssl and mod_jk could be used.
Create the Server Certificate
Create the server private key pair for the Tomcat host :
$ keytool -genkey -alias tomcat -keyalg RSA -keystore tomcat.jks -validity 365
This will generate a keystore called 'tomcat.jks' containing the RSA private key.
Generate the CSR
Now we must generate a CSR (Certificate Signing Request) for the Certification Authority to sign :
$ keytool -certreq -keyalg RSA -alias tomcat -file tomcat.csr -keystore tomcat.jks
This procedure will generate a file called 'tomcat.csr' containing the CSR.
Sign the CSR
Since we are acting as the Subject and as the Certification Authority, we must sign the CSR generated in the previous step : $ openssl ca -in tomcat.csr -out tomcat.cert
This procedure will generate your server certificate which will used during the SSL handshake, and used by the client to validate the server identity.
|
Skip this step if you are using third-party CAs (e.g. Verisign or Thaute), and submit the CSR using the available methods for the specific CA. |
|
If there is no CA configured in your OpenSSL setup this procedure will fail. |
Import the Certificate
We must now import our server's certificate in a keystore in order for Catalina to retrieve it and send it to the client during the SSL connection establishment. In order for the certificate to be imported, the CA certificate that signed the server certificate must be first imported into the keystore as a trusted CA :
$ keytool -import -alias root -keystore tomcat.jks -trustcacerts -file myca.cert
We are assuming that the 'myca.cert' file contains the CA certificate.
Once this procedure is completed we will be able to import the server certificate. In order for 'keytool' to be able to perform the import, the certificate must be supplied in the DER format.
$ openssl x509 -in tomcat.cert -out tomcat-der.cert -outform DER
The 'tomcat-der.cert' is now compatible with 'keytool' and can be imported in the following way : $ keytool -import -alias tomcat -file tomcat-der.cert -keystore tomcat.jks
This command will create an entry referenced as 'tomcat' in the 'tomcat.jks' keystore. When prompted for the passphrase for the keystore use 'changeit'.
Setup the Trusted CAs Store
On SSL connection establishment, the server requests the client to submit its certificate. Once received, before performing the actual authentication, the server performs certificate chain validation. Certificate chain verification is the process of making sure a given certificate chain is well-formed, valid, all properly signed, and trustworthy.
So we must add the CA certificate used to sign the server certificate, to the trusted CA keystore. Instead of adding it to the keystore that comes with the JDK, we'll create a separate one and add to it just this single certificate :
$ keytool -import -alias myca -keystore cacerts.jks -file myca.cert -trustcacerts
We're assuming that the CA certificate is located in the current directory in a file called 'myca.cert'. When prompted for the passphrase for the keystore use 'changeit'.
Enable SSL
In order for client certificates to be sent to the server an SSL connection must be established between the client and the server.
Move the 'tomcat.jks' and 'cacerts.jks' keystore files to the $CATALINA_HOME/conf directory.
Edit the $CATALINA_HOME/conf/server.xml file in order to enable and configure the SSL support in Tomcat :
<Server> ... <Service> ... <Connector port="8443" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" enableLookups="false" disableUploadTimeout="true" acceptCount="100" debug="1" scheme="https" secure="true" clientAuth="want" sslProtocol="TLS" keystoreFile="conf/tomcat.jks" keystorePass="changeit" truststoreFile="conf/cacerts.jks" truststorePass="changeit"/> </Service> ... </Server>
Try the SSL Connection
Before going further enabling strong authentication, check that the HTTPS in handled properly by contacting the following Url : https://localhost:8443/.
If succesfull, the Tomcat Welcome page should be displayed.
Create the Client Certificate
Lets create a certificate for the 'user1' user, in order to allow him/her to sign-on in JOSSO using client certificates :
$ openssl genrsa -des3 -out user1.key 1024
Generate the CSR for the Client Certificate
Next, generate a CSR (Certificate Signing Request) for the Certification Authority to sign :
$ openssl req -key user1.key -new -out user1.csr
This procedure will generate a file called 'user1.csr' containing the CSR.
Sign the Client Certificate
Since we are acting as the Subject and as the Certification Authority, we must sign the CSR generated in the previous step :
$ openssl ca -in user1.csr -out user1.cert
This procedure will generate user1's client certificate which will be sent to the server for validation.
|
Skip this step if you are using third-party CAs (e.g. Verisign or Thaute), and submit the CSR using the available methods for the specific CA. |
|
If there is no CA configured in your OpenSSL setup this procedure will fail. |
Generate a PKCS12 and import it in the Browser
Now that you have the private key and public key pair that go together you can package them in pkcs12-formatted file using the following procedure :
$ openssl pkcs12 -export -inkey user1.key -in user1.cert -out user1.pfx
This procedure will drop a file called 'user1.pfx', compatible with most browsers.
Startup your browser (e.g. IE, Firefox) and import it.
Enabling Strong Authentication
Add the user certificate
Once the user certificate is imported in the client, a similar procedure must be carried out in the server.
Edit the 'src/resources/josso-credentials.xml' file and add a new credential for the user identified as 'user1'.
Let's take a look at an example :
<josso-credentials> ... <credential-set> <key>user1</key> ... <credential> <name>userCertificate</name> <value> -----BEGIN CERTIFICATE----- MIIDjjCCAvegAwIBAgIBAjANBgkqhkiG9w0BAQQFADCBijELMAkGA1UEBhMCVVMx DDAKBgNVBAgTA04vQTEMMAoGA1UEBxMDTi9BMRswGQYDVQQKExJKT1NTTyBPcmdh bmlzYXRpb24xETAPBgNVBAsTCFNlY3VyaXR5MRIwEAYDVQQDEwlqb3Nzby5vcmcx GzAZBgkqhkiG9w0BCQEWDGNhQGpvc3NvLm9yZzAeFw0wNDExMTExOTQ3MTFaFw0w NTExMTExOTQ3MTFaMHUxCzAJBgNVBAYTAlVTMQwwCgYDVQQIEwNOL0ExGzAZBgNV BAoTEkpPU1NPIE9yZ2FuaXNhdGlvbjELMAkGA1UECxMCSVQxDjAMBgNVBAMTBXVz ZXIxMR4wHAYJKoZIhvcNAQkBFg91c2VyMUBqb3Nzby5vcmcwgZ8wDQYJKoZIhvcN AQEBBQADgY0AMIGJAoGBAKvwai6JYYycNRHfLyJNMehfUiv9tgEJcejTnsR1AwMS TFlk95RY09/T7vmDNaWw+aupFVu3yg+UOwc4lrh0nIR74HXbnCwBftyVYnqv0TJu VwFakOoRuwTnFyUw7WvzLkDzgqddoiua5f4jVpHCAeq8KuCDXmE9v6BUi2QPrbTZ AgMBAAGjggEWMIIBEjAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NM IEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUK9fZV0osJ85BRSQSAIZx tQZO9oUwgbcGA1UdIwSBrzCBrIAU+L2IUzRQ67GsKyNKdBK7nW5TsDuhgZCkgY0w gYoxCzAJBgNVBAYTAlVTMQwwCgYDVQQIEwNOL0ExDDAKBgNVBAcTA04vQTEbMBkG A1UEChMSSk9TU08gT3JnYW5pc2F0aW9uMREwDwYDVQQLEwhTZWN1cml0eTESMBAG A1UEAxMJam9zc28ub3JnMRswGQYJKoZIhvcNAQkBFgxjYUBqb3Nzby5vcmeCAQAw DQYJKoZIhvcNAQEEBQADgYEAaWaZypRdY7mZyKGOmJI32ElBlAmyLN+AN3TOMmg2 oi9Pgf7xCGoQ6nsuz52pwPAfL+zhfroCz2ZgY7wMf3BT5dVnZKF97b3KDwMABvTT 5wt3DcNSmhVCQDRkXDoTfclAeMNg7MXSy7E6XWhCwenu2P4llBCktAlclYFEzKkR sXY= -----END CERTIFICATE-----</value> </credential> </credential-set> ... </josso-credentials>
Replace the above certificate block with the 'user1' certificate content.
Note
The CN (common name) of the client certificate MUST match the credential key (e.g. user1).
Configure the Gateway
Having completed all the PKI-related configuration procedures, enable the strong authentication scheme in the following way :
<domain> ... <authenticator> ... <authentication-schemes> ... <!-- Strong Authentication Scheme --> <authentication-scheme> <name>strong-authentication</name> <class>org.josso.auth.scheme.X509CertificateAuthScheme</class> <!-- ================================================= --> <!-- Memory Credential Store --> <!-- ================================================= --> <credential-store> <class>org.josso.gateway.identity.service.store.MemoryIdentityStore</class> <credentialsFileName>josso-credentials.xml</credentialsFileName> </credential-store> <!-- ================================================= --> <!-- Credential Store Key adapter --> <!-- ================================================= --> <credential-store-key-adapter> <class>org.josso.gateway.identity.service.store.SimpleIdentityStoreKeyAdapter</class> </credential-store-key-adapter> </authentication-scheme> </authentication-schemes> </authenticator> </domain>
Configure the Agent
As mentioned before, since in order for the client certificates to be submitted to the server, an SSL connection must be established, the agent must point to the Gateway using HTTPS.
Let's take a look at an example Single Sign-On Agent configuration file :
<agent> <class>org.josso.tc50.agent.CatalinaSSOAgent</class> <gatewayLoginUrl>https://localhost:8443/josso/signon/login.do</gatewayLoginUrl> <gatewayLogoutUrl>https://localhost:8443/josso/signon/logout.do</gatewayLogoutUrl> ... </agent>
Test it
Build and deploy JOSSO following the Running section of the Setup HOW-TO.
Once Tomcat is up and running, contact the https://localhost:8443/. You should see yourself logged in without having to authenticate using the usual username/password pair.
Additional notes related to LDAP
If you plan to use LDAP to store users and credentials this notes may help you in the configuration process.
First you need to install the patch TODO. This patch fixes an issue related to binary attributes that is present in JOSSO 1.2
Configure the SSO Gateway
You will have to modify the josso-gateway-config.xml and use the following configuration for the strong-authentication scheme. Pay spetial attention to the credentialQueryString property value used in the credential store, the ;binary suffix may be needed to retrieve the userCertificate from some LDAP servers like OpenLDAP.
... <authentication-scheme> <name>strong-authentication</name> <class>org.josso.auth.scheme.X509CertificateAuthScheme</class> <!-- ================================================= --> <!-- LDAP Credential Store --> <!-- ================================================= --> <credential-store> <class>org.josso.gateway.identity.service.store.ldap.LDAPIdentityStore</class> <initialContextFactory>com.sun.jndi.ldap.LdapCtxFactory</initialContextFactory> <providerUrl>ldap://ldaphost</providerUrl> <securityPrincipal>cn=Manager,dc=my-domain,dc=com</securityPrincipal> <securityCredential>secret</securityCredential> <securityAuthentication>simple</securityAuthentication> <usersCtxDN>ou=People,dc=my-domain,dc=com</usersCtxDN> <principalUidAttributeID>uid</principalUidAttributeID> <rolesCtxDN>ou=Roles,dc=my-domain,dc=com</rolesCtxDN> <uidAttributeID>uniquemember</uidAttributeID> <roleAttributeID>cn</roleAttributeID> <credentialQueryString> uid=username,userCertificate;binary=userCertificate </credentialQueryString> <userPropertiesQueryString> mail=mail,cn=description </userPropertiesQueryString> </credential-store> <!-- ================================================= --> <!-- Credential Store Key adapter --> <!-- ================================================= --> <credential-store-key-adapter> <class>org.josso.gateway.identity.service.store.SimpleIdentityStoreKeyAdapter</class> </credential-store-key-adapter> </authentication-scheme> ...
|
You will have to modify this configuration to fit your needs, please check the LDAP Integration for more details. |
Using JXplorer to browse your LDAP
You can use JXplorer to browse you're LDAP server. If you're using OpenLDAP, you may need to configure JXplorer in order to work with binary attributes like the userCertificate. Edit the dxconfig.txt file located at $JXPLORER_HOME/dxconfig.txt and enable the sendVerboseBinarySuffix option :
... #option.ldap.sendVerboseBinarySuffix this appends a ';binary' suffix to binary attributes - needed for some directories option.ldap.sendVerboseBinarySuffix=true ...
For more information
Read the Developer HOW-TO.
Comments
Care to comment on this How-To? Help keep this document relevant by passing along any constructive feedback to the josso-docs