The most common use of X.509 certificate authentication is to authenticate a server using the SSL protocol, most commonly using HTTPS from a browser. The browser automatically verifies that the certificate presented by the server was issued (that is, digitally signed) by one of the trusted certificate authorities specified in the list it maintains.

You can also use the SSL protocol with "mutual authentication"; in which case the server will ask the client for a valid certificate as part of the SSL handshake. The server authenticates the client by verifying that its certificate was signed by a valid certificate authority. If a valid certificate was specified, it can be obtained through the servlet API in the application. The Spring Security module for X.509 retrieves the certificate using a filter. It maps a certificate to an application user and loads that user's set of granted credentials for use with the standard Spring Security framework.

You should become familiar with using certificates and setting up client authentication for your servlet container before attempting to use it with Spring Security. The bulk of the work is creating and installing the appropriate certificates and keys. For example, if you are using Tomcat, then read the instructions here https://tomcat. apache.org/tomcat-9.0-doc/ssl-howto.html. It is important that this is all working properly before you try using Spring Security.

Adding X.509-based authentication to your web application

Enabling X.509-based client authentication is very simple. You just need to add the <x509/> element to the http security namespace configuration.

<http>
...
    <x509 subject-principal-regex="CN=(.*?)," user-service-ref="userService"/>;
</http>

The element has two optional attributes:

  • subject-principal-regex. A regular expression used to extract the username from the subject name of the certificate. The default value is shown above. This is the username that will be passed to UserDetailsService to load the user's permissions.

  • user-service-ref. This is the identifier of the UserDetailsService bean that will be used with X.509. It is not needed if only one such bean is defined in the application context.

Subject-principal-regex must contain one group. For example, the standard expression "CN=(.*?)," matches the common name field. Thus, if the subject name on the certificate is "CN=Jimi Hendrix, OU=...", the user name will be "Jimi Hendrix". The match is not case sensitive. Thus, "emailAddress=(.*?)," would correspond to "EMAILADDRESS=jimi@hendrix.org,CN=…" and the username in the result will be "jimi@hendrix.org". If the client presents a certificate and a valid username is successfully retrieved, a valid Authentication object should appear in the security context. If the certificate was not found, or if the corresponding user could not be found, then the security context will remain empty. This means you can easily use X.509-based authentication with other options such as forms-based login.

Configuring the SSL protocol in Tomcat

In Sample repositories for Spring Security There are several pre-generated certificates. You can use them to enable an SSL protocol for testing purposes if you don't want to generate your own. The server.jks file contains the server certificate, private key, and certificate authority certificate. There are also several client certificate files for users from the sample applications. You can install them in your browser to authenticate the client using the SSL protocol

To run tomcat with SSL support, place the file server.jks in the tomcat directory called conf and add the following connector to the file server.xml

<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" scheme="https" secure="true"
                                                                clientAuth="true" sslProtocol="TLS"
                                                                keystoreFile="${catalina.home}/conf/server.jks"
                                                                keystoreType="JKS" keystorePass="password"
                                                                truststoreFile="${catalina.home}/conf/server.jks"
                                                                truststoreType="JKS" truststorePass="password"
/>

clientAuth can also be set to want if you want the SSL protocol to be installed successfully even if the client does not present a certificate. Clients that do not present a certificate will not be able to access objects protected by Spring Security unless you use an authentication mechanism other than X.509, such as form authentication.