Наиболее распространенное использование аутентификации на основе сертификата X.509 – это проверка подлинности сервера при использовании SSL-протокола, чаще всего при использовании HTTPS из браузера. Браузер автоматически проверяет, чтоб сертификат, представленный сервером, был выдан (т.е. подписан цифровой подписью) одним из доверенных центров сертификации, указанных в списке, который он ведет.

Вы также можете использовать SSL-протокол с "взаимной аутентификацией"; и в этом случае сервер будет запрашивать у клиента действительный сертификат в качестве элемента подтверждение установления связи по протоколу SSL. Сервер аутентифицирует клиента, проверяя, чтоб его сертификат был подписан допустимым центром сертификации. Если был указан действительный сертификат, его можно получить через API сервлета в приложении. Модуль Spring Security для X.509 извлекает сертификат с помощью фильтра. Он сопоставляет сертификат с пользователем приложения и загружает набор предоставленных полномочий этого пользователя для использования со стандартной инфраструктурой Spring Security.

Вам следует ознакомиться с использованием сертификатов и настройкой аутентификации клиента для вашего контейнера сервлетов, прежде чем пытаться использовать его с Spring Security. Основной объем работы заключается в создании и установке соответствующих сертификатов и ключей. Например, если вы используете Tomcat, то прочитайте инструкции здесь https://tomcat.apache.org/tomcat-9.0-doc/ssl-howto.html. Важно, чтобы это всё надлежаще работало до того, как вы будете пробовать использовать Spring Security.

Добавление аутентификации на основе X.509 в ваше веб-приложение

Активировать аутентификацию клиента на основе X.509 очень просто. Нужно лишь добавить элемент <x509/> в конфигурацию пространства имен безопасности http.

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

Элемент имеет два необязательных атрибута:

  • subject-principal-regex. Регулярное выражение, используемое для извлечения имени пользователя из имени субъекта сертификата. Значение по умолчанию показано выше. Это имя пользователя, которое будет передано UserDetailsService для загрузки полномочий пользователя.

  • user-service-ref. Это идентификатор бина UserDetailsService, который будет использоваться с X.509. Он не нужен, если в контексте приложения определен только один такой бин.

Subject-principal-regex должно содержать одну группу. Например, стандартное выражение "CN=(.*?)," соответствует полю общего имени. Таким образом, если имя субъекта в сертификате имеет вид "CN=Jimi Hendrix, OU=...", именем пользователя будет "Jimi Hendrix". Сопоставление не учитывает регистр. Таким образом, "emailAddress=(.*?)," будет соответствовать "EMAILADDRESS=jimi@hendrix.org,CN=…" а именем пользователя в результате будет "jimi@hendrix.org". Если клиент предъявляет сертификат, а действительное имя пользователя успешно извлечено, то в контексте безопасности должен появиться допустимый объект Authentication. Если сертификат не был найден, или если не удалось найти соответствующего пользователя, то контекст безопасности останется пустым. Это значит, что вы с легкостью можете использовать аутентификацию на основе X.509 с другими вариантами, такими как вход в систему на основе форм.

Настройка SSL-протокола в Tomcat

В репозитории с образцами для Spring Security есть несколько предварительно сгенерированных сертификатов. Вы можете использовать их для активации SSL-протокола в целях тестирования, если не хотите генерировать свой собственный. Файл server.jks содержит сертификат сервера, закрытый ключ и сертификат центра выдачи сертификатов. Также есть несколько файлов клиентских сертификатов для пользователей из образцов приложений. Вы можете установить их в свой браузер, чтобы осуществлять аутентификацию клиента по SSL-протоколу

Чтобы запустить tomcat с поддержкой SSL-протокола, поместите файл server.jks в каталог tomcat под названием conf и добавьте следующий коннектор в файл 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 можно также установить в значение want, если нужно, чтобы сочинения по SSL-протоколу были успешно установлены, даже если клиент не предъявил сертификат. Клиенты, не предъявившие сертификат, не смогут получить доступ к объектам, защищенным Spring Security, если вы не используете механизм аутентификации, отличный от X.509, например, аутентификацию по форме.