[jboss-user] [EJB3] - CLIENT-CERT enabled EJB3 in JBoss5.1

Administrator Administrator do-not-reply at jboss.com
Thu Jan 20 10:57:45 EST 2011


Administrator Administrator [http://community.jboss.org/people/admin] modified the document:

"CLIENT-CERT enabled EJB3 in JBoss5.1"

To view the document, visit: http://community.jboss.org/docs/DOC-15734

--------------------------------------------------------------
After have struggled a bit to setup this stuff, learning a lot of interesting things, so here I am writing a  clean, pure description of how set up a CLIENT-CERT enable EJB3 application in JBoss5.1 which uses a DatabaseCertLoginModule. The goal of this document is more a cookbook, than a reference one so please forgive lacks of explaination.


h4. The EJB class
Skipping the details of the implementaiton lets see only the top part of the class

import org.jboss.security.annotation.SecurityDomain;
import org.jboss.wsf.spi.annotation.WebContext;
import javax.annotation.security.RolesAllowed;
import javax.ejb.Stateless;
import javax.jws.WebService;
 
@WebService
@Stateless(name="dpws")
@SecurityDomain("discoveryDomain")
@RolesAllowed("OPERATOR")
@WebContext(contextRoot="/discovery", urlPattern="/dpws" ,authMethod="CLIENT-CERT", transportGuarantee="CONFIDENTIAL", secureWSDLAccess=false)
public class MyDiscovery implements MyDiscoveryRemote, MyDiscoveryLocal{
     
     @WebMethod(operationName="getNames")
     public String[] getNames() {
        return {"Fabio", "Marco"};
    }
}





Few notes:
** the authMethod (CLIENT-CERT) requires the client to send a certificate for the authentication
** the transportGuarantee (CONFIDENTIAL) requires JBoss to open an SSL connection
** the secureWSDLAccess (false) allow anyone to see the WSDL
For other options see the annotations documentation

* When packaging the EJB do not forget to add to the META-INF directory the jboss.xml file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE jboss PUBLIC -//JBoss//DTD JBOSS 3.2//EN http://www.jboss.org/j2ee/dtd/jboss_3_2.dtd>
<jboss>
    <security-domain>java:/jaas/discoveryDomain</security-domain>
</jboss>


Note that the +security-domain+ defers to the previous EJB's @SecurityDomains.

h4. Client's and Server's Certificates
Open a terminal windows, create a temporary folder, say "Certificates", and executes the following commands

Create the server keystore
 keytool -genkey -alias serverkeys -keyalg RSA -keystore server.keystore -storepass psw1 -keypass psw2




Export the server certificate
 keytool -export -alias serverkeys -keystore server.keystore -storepass psw1 -file server.cer


Create the client keystore
 keytool -genkey -alias clientkeys -keyalg RSA -keystore client.keystore -storepass pswA -keypass pswB


Export the client certificate
 keytool -export -alias clientkeys -keystore client.keystore -storepass pswA -file client.cer


Import the client certificate in the server.truststore
 keytool -import -v -keystore server.truststore  -storepass psw1 -file client.cer


Import the serevr certificate in the server.truststore
 keytool -import -v -keystore client.truststore  -storepass pswA -file server.cer

Anyway in a real world you just need only two steps:
1. a certify signed by a trusted Certification Authority (CA) for your client
2. import the CA certificate into your server.truststore
3. import the server certificate in your client.truststore
h4. 
h4. JBoss setup
As should be known, ${jboss.server.home.dir} indicates the $JBOSS_HOME/server/YourInstance directory.

* Copy the *server.keystore* and *server.truststore* files in ${jboss.server.home.dir}/conf

* Enable the JBoss's SSL connector editing the ${jboss.server.home.dir}/deploy/jbossweb.sar/server.xml and adding the following configuration

<!-- SSL/TLS Connector configuration using the admin devl guide keystore-->
      <Connector protocol="HTTP/1.1" SSLEnabled="true" 
           port="8443" address="${jboss.bind.address}"
           scheme="https" secure="true" clientAuth="false" 
           keystoreFile="${jboss.server.home.dir}/conf/server.keystore"
                keystorePass="psw1" 
           truststoreFile="${jboss.server.home.dir}/conf/server.truststore"
                truststorePass="psw2"
           sslProtocol = "TLS" />


* In the ${jboss.server.home.dir}/deploy folder create a *discovery-service.xml* file (or eventually edit one *-service.xml file you already use) and add

<!-- Configures the Discovery SecurityDomain -->

<mbean code="org.jboss.security.plugins.JaasSecurityDomain" name="jboss.security:service=SecurityDomain">
     <constructor>
          <arg type="java.lang.String" value="discoveryDomain" />
     </constructor>
     <attribute name="KeyStoreURL">file:${jboss.server.home.dir}/conf/server.keystore</attribute>
     <attribute name="KeyStorePass">pws1</attribute>
     <attribute name="TrustStoreURL">file:${jboss.server.home.dir}/conf/server.truststore</attribute>
     <attribute name="TrustStorePass">pws2</attribute>
     <depends>jboss.security:service=JaasSecurityManager</depends>
</mbean>

<mbean code="org.jboss.security.auth.login.DynamicLoginConfig" name="jboss:service=DynamicLoginConfig">
     <attribute name="AuthConfig">
          file:${jboss.server.home.dir}/deploy/discovery-security-config.xml
     </attribute>
     <depends optional-attribute-name="LoginConfigService">
          jboss.security:service=XMLLoginConfig
     </depends>
     <depends optional-attribute-name="SecurityManagerService">          jboss.security:service=JaasSecurityManager
     </depends>
</mbean>


     Notice that
** the first MBean defines the domain name (discoveryDomain) and the location of the key/truststore
** the second MBean defines the location of a specific policy configuraration file (so do not have to touch the ${jboss.server.home.dir}/conf/login-config.xml)

* creates ${jboss.server.home.dir}/deploy/discovery-security-config.xml file

<?xml version="1.0" encoding="UTF-8"?>
<policy>



     <application-policy name="discoveryDomain">


          <authentication>

               <login-module code="org.jboss.security.auth.spi.DatabaseCertLoginModule" flag = "required">


                    <module-option name="password-stacking">useFirstPass</module-option>

                    <module-option name="securityDomain">java:/jaas/discoveryDomain</module-option>


                    <module-option name="dsJndiName">jdbc/securityDS</module-option>

                    <module-option name="rolesQuery">select role, role_group from roles where principal_id=?</module-option>



                    <module-option name="verifier">ndg.common.jboss.security.CertVerifier</module-option>



               </login-module>



          </authentication>



     </application-policy>



</policy>



Notice that the policy defines a custom verifier, CertVerifier, which allow the application to customize the authenticationl; an empty, always trusting implementation, looks like


import java.security.KeyStore;
import java.security.cert.X509Certificate;
import org.jboss.security.auth.certs.X509CertificateVerifier;
 
public class CertVerifier implements X509CertificateVerifier {
    public boolean verify(X509Certificate arg0, String arg1, KeyStore arg2, KeyStore arg3) {
        System.out.println("CIAO!!!!!");
        return true;
    }
}

Notes that this clas should be packed in a separate jar file and deployed possibly in creates ${jboss.server.home.dir}/lib


* As should be clear the policy uses a DatabaseCertLoginModule class so we have to define a table in a given database using the roleTable.sql script

CREATE TABLE roles( role_group character varying NOT NULL DEFAULT 'Roles'::character varying,
"role" character varying NOT NULL,
principal_id character varying NOT NULL)

Notice that:
** The role_group column has 'Roles' as DEFAULT. This value MUST NOT be changed nor overrided.
** You need to insert *by hand* a row with your client role/PrincipalID. Such row will look like

"Roles";"OPERATOR";"CN=Maurizio Nagni, OU=BADC, O=STFC, L=Harwell, ST=Oxfordshire, C=UK"





* At the end you need a configuration file for the datasource similar to a *discovery-ds.xml*
<?xml version="1.0" encoding="UTF-8"?>
<datasources>
     <local-tx-datasource>
     <jndi-name>jdbc/securityDS</jndi-name>
     [.......]
     <local-tx-datasource>
<datasources>




h4. The Client setup
Once you deploy all the necessary machinery in JBoss you should verify that your WSDL is visible but none of the services is available. Now you can generate a WebService Client using any tool you like most (I used the Eclipse) to write a quick and dirty test like

import java.rmi.RemoteException;
import javax.security.auth.login.LoginContext;
import javax.xml.rpc.ServiceException;
 
public class Client {
 
    /**
     * @param args
     */
    public static void main(String[] args) {
        MyDiscoveryService svc = new MyDiscoveryServiceLocator();
        MyDiscovery ws;
        try {
            ws = svc.getMyDiscoveryPort();
            String[] listNames = ws.getNames(); //my webService method
            for (String name : listNames)
                System.out.println(name);
        } catch (ServiceException e) {
            e.printStackTrace();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }
}



Now you can run the Client class passing to the JVM the appropriate parameters, that is

-Djavax.net.ssl.keyStore=/myPathTo/client.keystore
-Djavax.net.ssl.keyStorePassword=pswA-Djavax.net.ssl.trustStore=/myPathTo/client.truststore
-Djavax.net.ssl.trustStorePassword=pswB

and verify that the client has been authenticated using its certificate and that the client name has been correctly associated to the role specified in the Roles table.
--------------------------------------------------------------

Comment by going to Community
[http://community.jboss.org/docs/DOC-15734]

Create a new document in EJB3 at Community
[http://community.jboss.org/choose-container!input.jspa?contentType=102&containerType=14&container=2029]
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/jboss-user/attachments/20110120/295c7e3a/attachment-0001.html 


More information about the jboss-user mailing list