Search code examples
apachessljbossx509ajp

How to access X509 subject.serialnumber in JBOSS 6 EAP icm AJP and SSL offloading


We have the following configuration:

  1. An Apache 2.2 Reverse proxy, terminating HTTPS for SSL offloading.
  2. A Jboss 6.1 EAP application server exposing SOAP services

The Apache is configured like is described in this article.

The SOAP services are implemented in a stateless session bean. Like this:

@WebContext( urlPattern = "/ba/test", authMethod = "BASIC", transportGuarantee = "NONE", secureWSDLAccess = false  )
@Stateless
@WebService
@SecurityDomain( "TestDomain" )
@RolesAllowed("TestRole")
public class TestSsb  {

    @WebMethod
    public String testMe(String in) {
        return "succeeded";
    }

}

A "TestDomain" has been configured.

In the current setup the serial number is transported via a dedicated HTTP header and we use a custom login-module in the JBOSS configuration xml file. This works.

However, we want to apply standard mechanisms whenever possible. Given that this setup is not that outlandish, there must be a way to access the X509 certificate information in the login-module configuration (e.g. with the BaseCertLoginModule).

There are 2 problems here:

  1. The documentation assumes a standard setup, in which also SSL termination (an as it seems authentication) is carried out by JBOSS.
  2. The documentation seems to assume that certificate "owner" is used for authorisation, whereas I need the subject.serialnumber and assign "TestRole" to it.

I'm not sure how to continue on this. Any help will be appreciated.


Solution

  • The solution works out of the box (after some playing around). The authMethod = "BASIC" has to be set to authMethod = "CLIENT-CERT". So:

    @WebContext( contextRoot = "aa/url", urlPattern = "*", authMethod = "CLIENT-CERT", transportGuarantee = "NONE", secureWSDLAccess = false )

    Next, you need to specify the roles / security domain as annotation:

    @SecurityDomain( "MyCertWebserviceDomain" )
    @DeclareRoles( value = {"MY_ROLE" } )

    By specifying a DatabaseCertLoginModule. The

    <security-domain name="MyCertWebserviceDomain">
       <authentication>
           <login-module code="org.jboss.security.auth.spi.DatabaseCertLoginModule" flag="required">
                <module-option name="dsJndiName" value="java:jboss/datasources/DS"/>
                <module-option name="verifier" value="org.jboss.security.auth.certs.AnyCertVerifier"/>
                <module-option name="rolesQuery" value="select role_name, 'Roles' from identity_role where identity IN(select regexp_replace(?, '.*SERIALNUMBER=([0-9]*), .*','\1') from dual)"/>
           </login-module>
        </authentication>
    </security-domain>
    

    The role (e.g. MY_ROLE) is fetched from the database and indexed by the serial number in the certificate.

    Protocol needs to be set to AJP in JBOSS.

    The identity can now be grabbed from the security principal: sessionContext.getCallePrincipal().getName().