More details on the error we get when using the <security-constraint>:
In the client, we do not see the CertificateRequest in the logs and get this
exception:
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:136)
at
com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1694)
at
com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:939)
at
com.sun.net.ssl.internal.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:746)
at
com.sun.net.ssl.internal.ssl.AppInputStream.read(AppInputStream.java:75)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
at java.io.BufferedInputStream.read(BufferedInputStream.java:237)
....
Server side, we get this exception:
Jun 15, 2010 12:25:09 PM org.apache.coyote.http11.Http11Processor action
WARNING: Exception getting SSL attributes
javax.net.ssl.SSLHandshakeException: renegotiation is not allowed
at
com.sun.net.ssl.internal.ssl.SSLSocketImpl.kickstartHandshake(SSLSocketImpl.java:1181)
at
com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1150)
at
com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1131)
at
org.apache.tomcat.util.net.jsse.JSSESupport.handShake(JSSESupport.java:156)
at
org.apache.tomcat.util.net.jsse.JSSESupport.getPeerCertificateChain(JSSESupport.java:138)
at
org.apache.coyote.http11.Http11Processor.action(Http11Processor.java:1108)
at org.apache.coyote.Request.action(Request.java:350)
at
org.apache.catalina.authenticator.SSLAuthenticator.authenticate(SSLAuthenticator.java:135)
at
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:491)
at
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849)
at
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at
org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454)
at java.lang.Thread.run(Thread.java:637)
and these logs:
Jun 15, 2010 12:25:09 PM org.apache.catalina.authenticator.SSLAuthenticator
authenticate
FINE: Looking up certificates
Jun 15, 2010 12:25:09 PM org.apache.catalina.authenticator.SSLAuthenticator
authenticate
FINE: No certificates included with this request
-Phil
On Tue, Jun 15, 2010 at 12:10 PM, Philippe Frangioni <[email protected]> wrote:
> Hi all,
>
> In our current project, we have a Spring Bean exposed as an Axis2 Web
> Service. The project is built with maven2 and produces a war. The Web
> Service is part of the Webapp (we do not use an aar). We're using Axis2
> 1.5.1 and the container we use is Tomcat 6.
> We want to set up Mutual SSL authentication. So we started with
> authenticating the server and it went fine.
> - The server has its own keystore (self signed certificate) and Tomcat has
> an SSL connector.
> - If we make a web service call with a browser, it's refused until we
> decide to trust the certificate.
> - If we make a web service call with our java client (using a
> RPCServiceClient), it's refused.
> - If we provide a truststore to our java client using
> -Djavax.net.ssl.trustStore and -Djavax.net.ssl.trustStorePassword, the call
> works fine.
>
> Second step was to have the server check the client certificate. So we gave
> both the server and the client a keystore and a truststore (the server and
> the client trusting each other's certificate).
>
> The results depend on Tomcat configuration: if the clientAuth parameter in
> the SSL connector is set to true (meaning a client certificate will be
> requested for all requests going through this connector):
>
> <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
> maxThreads="150" scheme="https" secure="true"
> keystoreFile="/path/server.keystore"
> keystorePass="changeit"
> truststoreFile="/path/server.keystore"
> truststorePass="changeit"
> clientAuth="true" sslProtocol="TLS" />
>
> Everything works fine:
> - If we make a web service call with a browser, it's refused because the
> browser is not configured to send a certificate.
> - If we make a web service call with our java client, it goes fine. We can
> see a CertificateRequest and the client sending its certificate in the debug
> logs.
>
> But the problem is that with clientAuth set to true, any request to the SSL
> connector requires a client certificate. And we just want to secure the web
> service calls.
>
> So it seems we have to set clientAuth to false and define a
> <security-constraint> in the web.xml of our webapp. But we cannot get it to
> work.
>
> Here is what we added to the web.xml:
>
> <!-- Define reference to the user database for looking up roles -->
> <resource-env-ref>
> <description>
> Link to the UserDatabase instance from which we request lists of
> defined role names. Typically, this will be connected to the global
> user database with a ResourceLink element in server.xml or the
> context
> configuration file for the Manager web application.
> </description>
> <resource-env-ref-name>users</resource-env-ref-name>
>
> <resource-env-ref-type>org.apache.catalina.UserDatabase</resource-env-ref-type>
> </resource-env-ref>
>
> <!-- Define a Security Constraint on this Application -->
> <security-constraint>
> <web-resource-collection>
> <web-resource-name>Our Webapp Web Services</web-resource-name>
> <url-pattern>/services/*</url-pattern>
> </web-resource-collection>
> <auth-constraint>
> <!-- NOTE: This role is not present in the default users file -->
> <role-name>secureaccess</role-name>
> </auth-constraint>
> </security-constraint>
>
> <!-- Define the Login Configuration for this Application -->
> <login-config>
> <auth-method>CLIENT-CERT</auth-method>
> <realm-name>Our Webapp Web Services</realm-name>
> </login-config>
>
> <!-- Security roles referenced by this web application -->
> <security-role>
> <description>
> The role that is required to call Websync Webapp Web Services
> </description>
> <role-name>secureaccess</role-name>
> </security-role>
>
> Here is what we added to tomcat-users.xml:
>
> <role rolename="secureaccess"/>
> <user username="CN=Client, OU=X, O=Y, L=Z, ST=XY, C=YZ" password="null"
> roles="secureaccess"/>
>
> There is probably something wrong here but we can't find what it is.
> One thing we're not sure is how the certificates are matched to the users
> in tomcat-users.xml.
> The username we're using for now, "CN=Client, OU=X, O=Y, L=Z, ST=XY, C=YZ",
> is the subject of our client certificate.
>
> Any help would be appreciated!
> I'm googling for 2 days and can't find what's wrong...
>
> Thanks,
> Phil
>