server.xml: =========== I set clientAuth to "want" tomcat-user.xml: ================ I create a role and an user with the ssl certificate metadata web.xml: ======== For a private URL on my webseite, I create a security constraint like this one: <security-constraint> <web-resource-collection> <web-resource-name>App</web-resource-name> <url-pattern>/protected.jsp</url-pattern> </web-resource-collection> <auth-constraint> <role-name>tomcat</role-name> </auth-constraint> <user-data-constraint> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> </security-constraint> <login-config> <auth-method>CLIENT-CERT</auth-method> </login-config> <security-role> <role-name>tomcat</role-name> </security-role> My results: (I try to access the restricted JSP-Page) =========== 1) When there is the RIGHT client certificate in the browser keystore: it works :-) 2) When there is the WRONG client certificate I get: HTTP Status 401 - Cannot authenticate with the provided credentials (this is ok, too) 3) When there is NO client certificate I get: HTTP Status 400 - No client certificate chain in this request 400 usually stands for a bad request or bad syntax. The Bug: ======== In case 3 I expect to get HTTP Status 401.
I understand your point, and have located the relevant code: org.apache.catalina.authenticator.SSLAuthenticator line 139. However, I'm not convinced the behavior you're asking for is correct: does the RFC say 401 (instead of 400, or more generally 4xx) is *required* for the case where a request has no certificates at all? If you could point out the relevant spec part that makes this clear, we can change the code.
A request that has no certificitates at all is not necessarily a bad request. When establishing a ssl connection, the server sends its certificate to the client. This includes the certificates of the CAs which are trusted by the server. The client only answers with certificates that are signed by one of the trusted CAs (directly or chained). When the client sends no certificate, it means that he has no matching certificate. This is an authentication issue and has nothing to do with the request syntax. RFC 2616 says for 400 Bad Request: "The request could not be understood by the server due to malformed syntax." As I stated before, a request that has no certificates attached (because there were none in the browser keystore) is not malformed. This behavior is specified in the SSL RFC 2264 "7.4.6. Client certificate (...) If no suitable certificate is available, the client should send a certificate message containing no certificates. (...)"
Point taken. I have fixed this in trunk and proposed it for 6.0.x and 5.5.x
This has been fixed in 6.0.x and will be included in 6.0.19 onwards.
This has been fixed in 5.5.x and will be included in 5.5.28 onwards.