SECTION: 400-Security TITLE: Client Certificates QUESTION: How do I use Client Certificate Authentication?

This is an overview of how to configure Jetty's SSL listener to require client certificates. There are only two steps:

1. Configure Jetty to use SSL. See for example Using Jetty and JSSE. Be sure to test the plain SSL configuration before turning on client certificates.
2. Configure the SSL listener to require client certificates. You have already configured a SunJsseListener to get SSL to work at all. Add a <Set/> tag to the configuration that sets NeedClientAuth to "true". The new tag is the last set in the example below:

         <Call name="addListener">
           <Arg>
             <New class="org.mortbay.http.SunJsseListener">
               <Set name="Port">8443</Set>
               <Set name="MinThreads">5</Set>
               <Set name="MaxThreads">255</Set>
               <Set name="MaxIdleTimeMs">50000</Set>
       	<Set name="Password">secretPassword</Set>
       	<Set name="KeyPassword">verySecretPassword</Set>
       	<Set name="NeedClientAuth">true</Set>
             </New>
           </Arg>
         </Call>

Just as when you configured the plain SSL listener, you may now access the SSL port with a URL like: `https://yourhost:8443/Dump`

If you get an javax.net.ssl.SSLException, check that you have remembered the s in https. Depending on your browser, you may see a dialog that asks which key the browser should send to the server. If the browser cannot provide JSSE with an acceptable user certificate, JSSE will drop the connection and not allow the user to proceed. Depending on the user's browser, the dropped connection may produce either a completely blank (white) screen or an error page.

Jetty also supports optional user certificates, where encountering a INTEGRAL or SECURE data constraint will request an SSL renegoatiation. Currently the RI of JSSE does not appear to support this, but other SSL implementations may.

Note that:

- The standard SSL port is 443. If the listener specifies this port, then the URL need not contain a port specification.
- There is no standard port for SSL with client authorization other than the overall standard SSL port 443. Thus if you want to run two SSL ports under your Jetty server, one with client certificates and one without, you will need to configure two SSL listeners and run at lease one of them on a non-standard port such as 8443.

The listener configuration above causes Jetty to add the certificate array obtained from the SSL listener, to the current HTTP request object under key javax.servlet.request.X509Certificate. This is a necessary condition for a web application that uses client-cert authentication via an entry in its web.xml file similar to `<login-config><auth-method>CLIENT-CERT</auth-method></login-config>` However, this entry is not sufficient for client-certificate authentication within a web application, as the certificates must be checked against a UserRealm implementation. The UserRealms provided with jetty do not provide any certificate handling. Within the JBoss J2EE server, the CLIENT-CERT auth method causes JBoss to save the certificate chain as the credential associated with the request. A custom written login module (JBoss currently includes no standard client-cert login module) can map this certificate chain into the appropriate list of J2EE roles.

Note that the object stored under request key javax.servlet.request.X509Certificate (or the JBoss certificate credential) is always an array of objects of class java.security.cert.X509Certificate. Per the Javadoc documentation for SSLSession.getPeerCertificates(), index #0 of this array is always the user's certificate. It is not clear if there is any way to configure JSSE or the browser to return anything other than the user's certificate. For most applications it seems prudent to use cert[0] only and not depend on the presence of anything else in the certificate chain.

### Environment and version information

This procedure was tested with Jetty embedded in JBoss 3.0.3. Jetty and JBoss were compiled using Sun's JDK 1.4.1.

Written by R.W. Shore, 31-Oct-2002.