在没有指定用户名的情况下使用CLIENT-CERT for Tomcat

时间:2012-08-01 13:46:35

标签: tomcat ssl web.xml client-certificates

我正在尝试让Tomcat Web应用程序对传入连接使用客户端证书身份验证。在server.xml中使用clientAuth = true时,一切正常,但由于其他应用程序在同一服务器上运行,我们无法在生产环境中使用它。

是否有办法形成web.xml文档,以便以与clientAuth = true相同的方式强制应用程序的客户端证书使用?似乎使用CLIENT-CERT设置还要求您为每个要访问系统的证书设置tomcat用户帐户?我们需要能够允许来自指定CA(在服务器信任库中设置)的所有证书,其中主题与特定规则匹配(在实际应用程序中检查)。我希望像下面这样的东西能起作用,但还没有运气!

<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 个答案:

答案 0 :(得分:4)

首先,听起来你想要clientAuth=want而不是clientAuth=true:这将允许客户提供证书,但绝对不需要证书。

当您使用任何类型的身份验证时,Tomcat(或任何类似的servlet容器)必须能够构建一个Principal对象 - 一个具有名称(通常是用户名)的对象。然后,容器必须确定用户具有哪些角色才能正确授权特定请求。因此,Tomcat需要事先了解用户才能使授权工作。

另一方面,如果您不需要任何授权,可以设置clientAuth=want,然后使用Filter验证证书。如果您已经在进行自己的检查,则无需使用CLIENT-CERT身份验证。

答案 1 :(得分:2)

我只是在解决上述问题的解决方案,最后找到了解决方案:

  1. 使用连接器clientAuth =“false”属性配置tomcat(否则与服务器的所有安全连接都将执行相互,客户端服务器,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"/>
    

    &LT;用户名=“EMAILADDRESS=hamzas100@yahoo.com,CN = KS,OU = OFF,O = OFS,L =布哈拉,
       ST = Bukhara,C = UZ“password =”“roles =”manager“/&gt;

  4. 放入浏览器(或curl)地址行:

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

  5. 为此,您必须将证书添加到浏览器个人证书列表中(如果您使用浏览器进行测试)。我尝试过使用Mozilla Firefox,它很容易让你这样做。(但它只接受b12证书,所以建议你应该使用带有java keytool的openssl)。如果一切配置正确,那么您将从mozilla获得提示,从现有的证书中选择证书。如果您正在使用curl(它用于自动Web界面测试,那么请使用以下命令行进行测试(我刚刚给出了一个示例。)请注意,您应该选择导入信任库的证书。

    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

  6. 注意:我的连接器如下所示:

    <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">