Tomcat secure access

2019-02-19 08:22发布

问题:

I have two Web Services (MyService and MyProtectedService). I want both going under the same port HTTPS but only the protected one to have client authentication (clientAuth=true).

All the security is working fine, but the problem is that the client auth is ON for both services, not only for the protected one. What I would like is remove the client auth for one of them, or apply the client auth to the other only.

Does anyone have any hint? Thanks

In the web.xml:

<security-constraint>
    <web-resource-collection>
        <web-resource-name>protected element</web-resource-name>
        <description/>
        <url-pattern>/MyProtectedService</url-pattern>
    </web-resource-collection>
    <user-data-constraint>
        <transport-guarantee>CONFIDENTIAL</transport-guarantee>
    </user-data-constraint>
</security-constraint>

UPDATE: I tried to divide the service in two constrains:

<security-constraint>
    <web-resource-collection>
        <web-resource-name>OpenService</web-resource-name>
        <description/>
        <url-pattern>/OpenService</url-pattern>
    </web-resource-collection>
</security-constraint>

<security-constraint>
    <web-resource-collection>
        <web-resource-name>protected</web-resource-name>
        <description/>
        <url-pattern>/MyProtectedService</url-pattern>
    </web-resource-collection>
    <user-data-constraint>
        <transport-guarantee>CONFIDENTIAL</transport-guarantee>
    </user-data-constraint>
    <login-config>
        <auth-metod>CLIENT-CERT</auth-metod>
    </login-config>
</security-constraint>

And have ClientAuth=false in server.xml.

But then I can access this without any client authentication: https://MACHINE/MyProtectedService/MyProtectedService?wsdl

回答1:

The approach is to have two separate security constraints even though the one for the public service has no constraint at all (neither a auth-constraint nor a user-data-constraint). It assumes that the two service have different URLs which is most likely the case:

<security-role>
    <role-name>ProtectedServiceRole</role-name>
</security-role>

<security-constraint>
    <web-resource-collection>
        <web-resource-name>Public Service</web-resource-name>
        <url-pattern>/PublicService/*</url-pattern>
    </web-resource-collection>
</security-constraint>

<security-constraint>
    <web-resource-collection>
        <web-resource-name>Protected Service</web-resource-name>
        <url-pattern>/ProtectedService/*</url-pattern>
    </web-resource-collection>
    <user-data-constraint>
        <transport-guarantee>CONFIDENTIAL</transport-guarantee>
    </user-data-constraint>
    <auth-constraint>
        <role-name>ProtectedServiceRole</role-name>
    </auth-constraint>
</security-constraint>

The role name specified in the auth-constraint will trigger an authentication.

Update:

I'm afraid I haven't properly read your question and overlooked the certificate authentication part. Though I have used it in the past, I never had the mixed setup you require so I can only give some options what you could try next:

Currently you require the authentication on the transport level. That's to low-level and too early. Have you tried setting clientAuth to false and instead add the following lines to your web.xml:

<login-config>
    <auth-method>CLIENT-CERT</auth-method>
</login-config>

Another approach would be to use two differnt ports for the two services. For that, you define two different connectors in the server.xml.