4 Replies Latest reply on Dec 11, 2011 10:39 PM by julieh

    Accessing Client Certificates in JBoss Servlet with proxy HTTP Server

    julieh

      Hi.

       

      I am having some issues accessing Client Certificates from within my JBoss Servlet.

      I am not really sure if I have my Jboss configuration correct for getting access to the Client Certificates when using a proxy HTTP server.

       

      Firstly I am using Jboss 6.1.0.Final.

       

      I have an IBM HTTP Server setup which directs calls to particular URLs through to my Jboss server.

       

      I have 2 web applications installed.

      One web application handles the URLS which require Basic Authentication.

      The other web application handles those URLs where the client provides a CLient Certificate.

       

      The Basic Authentication app is working well.

       

      However I cannot get the Client Certificate web application working, in that I cannot get access to the Client Certificate in the request.

       

      I am pretty confident that I have the HTTP server set up correctly. (The project I am working on is to migrate an application from Websphere application server to Jboss. I have exactly the same setup in the HTTP server for the URLS that are directed to Jboss, as for the URLs that are directed to WAS, and the client certificate is contained in the request when the request gets to the servlet installed in WAS).

      ps. I have the SSLClientAuth set as optional in HTTP Server config, as I don't want HTTP Server to enforce the existance of the client cert, I want that to be controlled by the application. 

       

      So that leads me to conclude that I have not set up JBoss correctly.

       

      I have the security constraint section of the web.xml set up as follows :

       

            <security-constraint>

               <web-resource-collection>

                  <web-resource-name>Axis Test Protected Area</web-resource-name>

                  <url-pattern>/inbound/AS2</url-pattern>

                  <url-pattern>/inbound/ACSN</url-pattern>

                  <url-pattern>/inbound/wM</url-pattern>

                  <url-pattern>/inbound/EBXML</url-pattern>

                  <http-method>POST</http-method>

                  <http-method>GET</http-method>

               </web-resource-collection>

               <auth-constraint>

                  <role-name>*</role-name>

               </auth-constraint>

               <user-data-constraint>

                  <transport-guarantee>NONE</transport-guarantee>

               </user-data-constraint>

            </security-constraint>

            <login-config>

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

               <realm-name>Test</realm-name>

            </login-config> 

       

       

      So my understanding is that this means that the resource is secured, and will request a Client Certificate.

       

      Based on this assumption, I don't think that I need anything in the Server.xml which forces a client certificate to be provided (as the HTTP Server will be authenticating the Client Cert IF it is provided)

      Therefore I have the following set up for the Connector in the Server.xml

       

       

            <Connector protocol="HTTP/1.1" SSLEnabled="true" allowTrace="true"
                 port="${jboss.web.https.port}" address="${jboss.bind.address}"
                 scheme="https" secure="true" clientAuth="false"
                 keystoreFile="${jboss.server.home.dir}/conf/was7-plugin-key.jks"
                 keystorePass="axis2002" sslProtocol = "TLS"
                 />

       

       

       

      So using the above config, I have initially attempted to access the secured URL (inbound/AS2) directly through Jboss (ie taking HTTP Server out of the equation), but without any luck.

       

      Using the above config, and accessing the URL from a Web Browser (in which I have installed a cert), a Client Certificate is requested. I select the cert in the web browser, but it is never passed in the request, and my servlet doesn't initiate. This is part of the message I get in the server.log :

       

       

      INFO  [org.apache.catalina.core.ContainerBase.[jboss.web].[localhost]] (http-AXBAPPST02%2F1.93.199.91-9081-1) ---------------------------------------------------------------
      INFO  [org.apache.catalina.core.ContainerBase.[jboss.web].[localhost]] (http-AXBAPPST02%2F1.93.199.91-9081-1)           authType=null
      INFO  [org.apache.catalina.core.ContainerBase.[jboss.web].[localhost]] (http-AXBAPPST02%2F1.93.199.91-9081-1)      contentLength=-1
      INFO  [org.apache.catalina.core.ContainerBase.[jboss.web].[localhost]] (http-AXBAPPST02%2F1.93.199.91-9081-1)        contentType=text/html;charset=utf-8
      INFO  [org.apache.catalina.core.ContainerBase.[jboss.web].[localhost]] (http-AXBAPPST02%2F1.93.199.91-9081-1)             header=X-Powered-By=Servlet/3.0; JBossAS-6
      INFO  [org.apache.catalina.core.ContainerBase.[jboss.web].[localhost]] (http-AXBAPPST02%2F1.93.199.91-9081-1)             header=Pragma=No-cache
      INFO  [org.apache.catalina.core.ContainerBase.[jboss.web].[localhost]] (http-AXBAPPST02%2F1.93.199.91-9081-1)             header=Cache-Control=no-cache
      INFO  [org.apache.catalina.core.ContainerBase.[jboss.web].[localhost]] (http-AXBAPPST02%2F1.93.199.91-9081-1)             header=Expires=Thu, 01 Jan 1970 10:00:00 EST
      INFO  [org.apache.catalina.core.ContainerBase.[jboss.web].[localhost]] (http-AXBAPPST02%2F1.93.199.91-9081-1)            message=No client certificate chain in this request
      INFO  [org.apache.catalina.core.ContainerBase.[jboss.web].[localhost]] (http-AXBAPPST02%2F1.93.199.91-9081-1)         remoteUser=null
      INFO  [org.apache.catalina.core.ContainerBase.[jboss.web].[localhost]] (http-AXBAPPST02%2F1.93.199.91-9081-1)             status=401
      INFO  [org.apache.catalina.core.ContainerBase.[jboss.web].[localhost]] (http-AXBAPPST02%2F1.93.199.91-9081-1) ===============================================================

       

       

       

      I have also tried setting clientAuth to 'want' and adding a truststoreFile and truststorePass (and NOT having a truststoreFile and Pass) to the Connector in Server.xml. This results in being asked for a client cert in the browser, but absolutely no logging in the server.

       

       

       

       

      Any pointers in helping to get this set up would be REALLY appreciated.

       

       

      Thanks

       

        • 1. Re: Accessing Client Certificates in JBoss Servlet with proxy HTTP Server
          jfclere
          1 of 1 people found this helpful
          • 2. Re: Accessing Client Certificates in JBoss Servlet with proxy HTTP Server
            julieh

            Thanks Jean-Frederic,

             

            This has certainly gone some way to helping.

             

            After implementing this, I can see in the logging in Jboss that this information is being passed into JBoss. All the information that is, except for the CLient Certificate.

             

            I added the following to http.conf :

             

            RequestHeader set SSL_CLIENT_CERT "%{SSL_CLIENT_CERT}s"
            RequestHeader set SSL_CIPHER "%{SSL_CIPHER}s"
            RequestHeader set SSL_SESSION_ID "%{SSL_SESSION_ID}s"
            RequestHeader set SSL_CIPHER_USEKEYSIZE "%{SSL_CIPHER_USEKEYSIZE}s"

             

            The logging in jBoss now shows the addition of the following headers to the request :

             

            [org.apache.catalina.core.ContainerBase.[jboss.web].[localhost]] (http-AXBAPPST02%2F1.93.199.91-9081-1)             header=ssl_client_cert=(null)
            [org.apache.catalina.core.ContainerBase.[jboss.web].[localhost]] (http-AXBAPPST02%2F1.93.199.91-9081-1)             header=ssl_cipher=SSL_RSA_WITH_RC4_128_MD5
            [org.apache.catalina.core.ContainerBase.[jboss.web].[localhost]] (http-AXBAPPST02%2F1.93.199.91-9081-1)             header=ssl_session_id=FB8AAPKsv8soNhb8Nb1+GTAizUZYWFhYpKbhThkAAAA=
            [org.apache.catalina.core.ContainerBase.[jboss.web].[localhost]] (http-AXBAPPST02%2F1.93.199.91-9081-1)             header=ssl_cipher_usekeysize=128

            The valve then throws an exception :

             

            2011-12-09 16:11:49,058 ERROR [org.apache.catalina.connector.CoyoteAdapter] (http-AXBAPPST02%2F1.93.199.91-9081-1) An exception or error occurred in the container during the request processing: java.lang.StringIndexOutOfBoundsException: String index out of range: -48
            at java.lang.String.substring(String.java:1938) [:1.6.0_13]
            at SSLValve.invoke(SSLValve.java:77) at org.apache.catalina.valves.RequestDumperValve.invoke(RequestDumperValve.java:151)

             

            NOt quite sure why this happens, as the Valve code checks that the request.getHeader("ssl_client_cert") is not null before doing String manipulation.....but that is not the issue at the moment - I'm guessing this won't happen one I get the client cert in.

             

             

            The problem is that Jboss is still not requesting the Client Cert.

            As mentioned in my previous post, the web app is set up for CLIENT-CERT authorisation, and I have tried both 'false' and 'want' in the Connector's clientAuth property in Server.xml

            The http.conf in HTTPServer is set up to have SSLClientAuth optional.

             

            But none of these setups seems to be asking the client to provide a client cert.

             

            Do you have any other suggestions for what could be causing this problem?

             

            Thanks

            Julie

            • 3. Re: Accessing Client Certificates in JBoss Servlet with proxy HTTP Server
              jfclere

              You must get httpd to ask for the client certificates it will be forwarded to jboss.

              (see SSLVerifyClient in mod_ssl docs).

              • 4. Re: Accessing Client Certificates in JBoss Servlet with proxy HTTP Server
                julieh

                Thanks Jean-Frederic.

                 

                I already had the SSLClientAuth set to optional in the http.conf.

                But this did not seem to be causing the client cert to be requested.

                 

                I did some further research however and found that my issue is probably with my means of testing.

                I have been testing the client certificate requesting by typing in the URL in my web browser (IE) and expecting to be prompted for the client certificate.

                I have found an article however that states the following :

                 

                Internet Explorer 7 does not seem to understand Certificate Request messages that span multiple SSL records. The most common cause for generating such a set of records for a single message are having an extremely large number of personal certificates or signer certificates in the CMS KDB file used on the server.

                 

                 

                This happens to be the case with our KDB store (though I am not sure what constitutes an 'extremely large number').

                 

                I have tested using another client, and I can now see the client certificate being included in the request, and can access the client certificate in my servlet.

                 

                Thanks very much for taking the time to help me out.

                Regards

                Julie