Использование CLIENT-CERT для Tomcat без указания имени пользователя
Я пытаюсь заставить веб-приложение Tomcat использовать аутентификацию сертификата клиента для входящих соединений. Все отлично работает при использовании clientAuth=true в server.xml, однако из-за других приложений, работающих на том же сервере, мы не можем использовать это в производственной среде.
Есть ли способ сформировать документ web.xml так, чтобы он принудительно использовал сертификат клиента для приложения так же, как clientAuth=true? Кажется, что использование параметра CLIENT-CERT также требует настройки учетной записи пользователя tomcat для каждого сертификата, который должен получить доступ к вашей системе? Мы должны иметь возможность разрешить все сертификаты, полученные из указанного центра сертификации (установленного в хранилище доверенных сертификатов сервера), где субъект соответствует определенным правилам (проверено в реальном приложении). Я надеялся, что что-то вроде следующего будет работать, но пока не повезло!
<security-constraint>
<web-resource-collection>
<web-resource-name>Everything</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
<login-config>
<auth-method>CLIENT-CERT</auth-method>
</login-config>
2 ответа
Во-первых, это звучит так, как вы хотите clientAuth=want
вместо clientAuth=true
: это позволит клиенту предоставить сертификат, но не обязательно требует его.
Когда вы используете аутентификацию любого рода, Tomcat (или любой сервлет-контейнер в этом отношении) должен быть в состоянии создать Principal
объект из него - тот, у которого есть имя (обычно имя пользователя). Затем контейнер должен решить, какие роли имеет пользователь, чтобы правильно авторизовать конкретный запрос. Таким образом, Tomcat должен знать о пользователях заранее, чтобы авторизация работала.
С другой стороны, если вам не нужна авторизация, вы можете установить clientAuth=want
а затем использовать Filter
проверить сертификат. Там нет необходимости использовать CLIENT-CERT
аутентификация, если вы уже делаете свою собственную проверку.
Я просто искал решение вышеупомянутой проблемы и наконец нашел решение:
Настройте tomcat с атрибутом соединителя clientAuth="false" (в противном случае все безопасные соединения с сервером будут выполнять взаимную аутентификацию клиента-сервера и ssl).
Добавьте следующее в web.xml (я только что показал здесь пример)
<security-constraint> <web-resource-collection> <url-pattern>/LoginTestServlet1</url-pattern> <http-method>GET</http-method> <http-method>POST</http-method> </web-resource-collection> <auth-constraint> <role-name>manager</role-name> </auth-constraint> <user-data-constraint> <!-- transport-guarantee can be CONFIDENTIAL, INTEGRAL, or NONE --> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> </security-constraint> <security-constraint> <web-resource-collection> <url-pattern>/LoginTestServlet2</url-pattern> <http-method>GET</http-method> <http-method>POST</http-method> </web-resource-collection> <auth-constraint> <role-name>manager</role-name> </auth-constraint> <!-- <user-data-constraint> transport-guarantee can be CONFIDENTIAL, INTEGRAL, or NONE <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> --> </security-constraint> <login-config> <auth-method>CLIENT-CERT</auth-method> <realm-name>certificate</realm-name> </login-config>
менеджер
В tomcat users-users.xml добавьте следующее (пожалуйста, обратите внимание, что если хранилище доверия имеет почти идентичные сертификаты, вы должны четко идентифицировать свой сертификат следующим образом)
<role rolename="manager"/>
вставьте в адресную строку браузера (или curl):
https://yourdomain.com:8443/LoginTest/LoginTestServlet1 или
https://yourdomain.com:8443/LoginTest/LoginTestServlet2Чтобы это работало, вы должны добавить сертификат в личный список сертификатов браузера (если вы тестируете с браузером). Я пробовал с Mozilla Firefox, и он легко позволит вам сделать это (но он принимает только сертификат b12, поэтому рекомендуется использовать openssl с java keytool). Если все настроено правильно, вы получите приглашение от mozilla для выбора сертификата из существующих. Если вы используете curl(он используется для автоматического тестирования веб-интерфейсов, используйте следующую строку для проверки (я только что привел здесь пример). Обратите внимание, что вы должны выбрать сертификат, который вы импортировали в доверенное хранилище.
curl -s -k --cert selfsigned.pem --key key.pem -v --anyauth https://yourdomain.com:8443/LoginTest/LoginTestServlet1 --cacert selfsigned.pem или curl -s -k --cert selfsigned.pem --key key.pem -v --anyauth http://yourdomain.com:8080/LoginTest/LoginTestServlet2 --cacert selfsigned.pem
Примечание: мой разъем выглядит следующим образом:
<Connector port="8443"
maxThreads="150" scheme="https" secure="true" SSLEnabled="true"
sslProtocol="TLS" keystoreType="PKCS12" truststoreType="PKCS12" clientAuth="false"
keystoreFile="C:/Program Files/glassfish-3.1.2/glassfish/domains/domain1/config/cacerts.pkcs12"
truststoreFile= "C:/Program Files/glassfish-3.1.2/glassfish/domains/domain1/config/cacerts.pkcs12"
truststorePass="changeit"
keystorePass="changeit"
protocol="org.apache.coyote.http11.Http11Protocol">