[[servlet-x509]]
= X.509 Authentication

[[x509-overview]]
The most common use of X.509 certificate authentication is in verifying the identity of a server when using SSL, most commonly when using HTTPS from a browser.
The browser automatically checks that the certificate presented by a server has been issued (digitally signed) by one of a list of trusted certificate authorities that it maintains.

You can also use SSL with "`mutual authentication`". The server then requests a valid certificate from the client as part of the SSL handshake.
The server authenticates the client by checking that its certificate is signed by an acceptable authority.
If a valid certificate has been provided, it can be obtained through the servlet API in an application.
The Spring Security X.509 module extracts the certificate by using a filter.
It maps the certificate to an application user and loads that user's set of granted authorities for use with the standard Spring Security infrastructure.

You can also use SSL with "`mutual authentication`". The server then requests a valid certificate from the client as part of the SSL handshake.
The server authenticates the client by checking that its certificate is signed by an acceptable authority.
For example, if you use Tomcat, you should read the https://tomcat.apache.org/tomcat-10.1-doc/ssl-howto.html[Tomcat SSL instructions].
You should get this working before trying it out with Spring Security.


== Adding X.509 Authentication to Your Web Application
Enabling X.509 client authentication is very straightforward.
To do so, add the `<x509/>` element to your http security namespace configuration:

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

The element has two optional attributes:

* `subject-principal-regex`.
The regular expression used to extract a username from the certificate's subject name.
The default value is shown in the preceding listing.
This is the username that is passed to the `UserDetailsService` to load the authorities for the user.
* `user-service-ref`.
This is the bean ID of the `UserDetailsService` to be used with X.509.
It is not needed if there is only one defined in your application context.

The `subject-principal-regex` should contain a single group.
For example, the default expression (`CN=(.*?)`) matches the common name field.
So, if the subject name in the certificate is "CN=Jimi Hendrix, OU=...", this gives a user name of "Jimi Hendrix".
The matches are case insensitive.
So "emailAddress=(+.*?+)," matches "EMAILADDRESS=jimi@hendrix.org,CN=...", giving a user name "jimi@hendrix.org".
If the client presents a certificate and a valid username is successfully extracted, there should be a valid `Authentication` object in the security context.
If no certificate is found or no corresponding user could be found, the security context remains empty.
This means that you can use X.509 authentication with other options, such as a form-based login.

[[x509-ssl-config]]
== Setting up SSL in Tomcat
There are some pre-generated certificates in the {gh-samples-url}/servlet/java-configuration/authentication/x509/server[Spring Security Samples repository].
You can use these to enable SSL for testing if you do not want to generate your own.
The `server.jks` file contains the server certificate, the private key, and the issuing authority certificate.
There are also some client certificate files for the users from the sample applications.
You can install these in your browser to enable SSL client authentication.

To run tomcat with SSL support, drop the `server.jks` file into the tomcat `conf` directory and add the following connector to the `server.xml` file:

[source,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 still want SSL connections to succeed even if the client does not provide a certificate.
Clients that do not present a certificate cannot access any objects secured by Spring Security unless you use a non-X.509 authentication mechanism, such as form authentication.

