For something like a week now I've been trying to read SSL Client
Certificate information using:
Apache 2.0.44, Tomcat 4.1.18, mod_jk built from the connectors-4.1.18
package and the mod_ssl that comes with the 2.0.44 source
distribution. I have finally got things working in my environment in
a satisfactory way, and I thought I'd take a minute to post to the list
some of what I learned.
Thanks to all of you who responded to my requests for help. Most of the
reponses were helpful and all were appreciated.
First of all, I never could get mod_jk2 to pass SSL environment
variables between Apache and Tomcat. The only one that ever seemed to
get through was "javax.servlet.request.cipher_suite". After a couple of
frustrating days, I gave up on mod_jk2 and went back to mod_jk. (If
anybody knows how to make this work with mod_jk2, I'd still like to hear
about it.) I set this up according to the excellent instructions at:
http://jakarta.apache.org/tomcat/tomcat-3.2-doc/tomcat-ssl-howto.html
In my httpd.conf file, I put the following directives in the global area:
### instruct mod_jk to play nicely with mod_ssl ##
<IfModule mod_jk.c>
JkExtractSSL On
JkHTTPSIndicator HTTPS
JkSESSIONIndicator SSL_SESSION_ID
JkCIPHERIndicator SSL_CIPHER
JkCERTSIndicator SSL_CLIENT_CERT
</IfModule>
and in the VirtualHost section that controls the Tomcat context from
which I wish to read client certificate data:
<Location /safe>
SSLOptions +FakeBasicAuth +ExportCertData +StdEnvVars
SSLVerifyClient require
SSLVerifyDepth 1
SSLRequireSSL
</Location>
Obviously, you should substitute your context name where I have "safe".
Once Apache, Tomcat and mod_jk were all properly configured and playing
nicely with one another, the next challenge was to write some java code
in a servlet to get to the client certificate information. This proved
to be pretty easy, except for one avoidable blunder that I'll talk about
in a minute. Here's a code snippet that works for me:
....
import java.security.cert.*;
....
try {
Object o = request.getAttribute(
"javax.servlet.request.X509Certificate");
if (o != null) {
X509Certificate certs[] = (X509Certificate[])o;
X509Certificate cert = certs[0];
// Get the Distinguished Name for the user.
String n = cert.getSubjectDN().getName();
}
else
out.println = "Object was null.";
}
catch (Exception exc) {
out.println = exc.toString();
}
....
Nothing to it. Except that now I want to rant for a bit. The Servlet
2.3 specification says (in SRV.4.7):
....If there is an SSL certificate associated with the request, it must
be exposed by the servlet container to the servlet programmer as an
array of objects of type java.security.cert.X509Certificate and
accessible via a ServletRequest attribute of
javax.servlet.request.X509Certificate...
Now, I KNOW it's my fault for not reading carefully, but I spent hours
trying to figure out why I was getting a ClassCast Exception for trying
to cast the request attribute object to
"javax.security.cert.X509Certificate[]". (The problem, in case it has
escaped you as it did me for so long, is that I used "javax" instead of
"java".) My mistake would have been a lot more transparent if not for
the fact that there does exist a class named
"javax.security.cert.X509Certificate". Now, I suppose there's a good
reason for this but, damn, do we really need to have 2 X509Certificate
classes, one in the java.security.cert package and the other in the
javax.security.cert package? Yikes.
Anyway, I hope this synopsis is of some value. And thanks again to all
those who tried to help me.
Robert Dana
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
- Reading client certificates Robert Dana
- Re: Reading client certificates Will Hartung
- RE: Reading client certificates Filip Hanik
- RE: Reading client certificates Julius Davies
- RE: Reading client certificates Larry Meadors
- Re: Reading client certificates Robert Dana
- Re: Reading client certificates Martin Craig
