Использование 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 аутентификация, если вы уже делаете свою собственную проверку.

Я просто искал решение вышеупомянутой проблемы и наконец нашел решение:

  1. Настройте tomcat с атрибутом соединителя clientAuth="false" (в противном случае все безопасные соединения с сервером будут выполнять взаимную аутентификацию клиента-сервера и ssl).

  2. Добавьте следующее в 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>
    

    менеджер

  3. В tomcat users-users.xml добавьте следующее (пожалуйста, обратите внимание, что если хранилище доверия имеет почти идентичные сертификаты, вы должны четко идентифицировать свой сертификат следующим образом)

    <role rolename="manager"/>
    

  4. вставьте в адресную строку браузера (или curl):

    https://yourdomain.com:8443/LoginTest/LoginTestServlet1 или
    https://yourdomain.com:8443/LoginTest/LoginTestServlet2

  5. Чтобы это работало, вы должны добавить сертификат в личный список сертификатов браузера (если вы тестируете с браузером). Я пробовал с 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">
Другие вопросы по тегам