Setting up CA and generating the CA certThe CA is set up according to
these instructions .
Generating the user key/CSR with OpenSSLYou can generate the CSR with this OpenSSL commands:
openssl req -new -nodes -keyout democompany1.key -out democompany1.csr -days 365
Generating the user key/CSR with keytoolWhen using a Java client for the webservice you probably want to use all the JSSE stack. So you are practically binded to the JKS keystore implementation. JKS keystore management is accomplished with "keytool" from command line. One keytool quirk is that you can not export/import private keys from/to a JKS keystore with the "keytool" command. So you must use Java code directly to manage your keys in a keystore or accept that restriction. Thus when using a Java client we need to generate our private key inside a JKS keystore from the beginning. You can generate the private key and the CSR with these keytool commands:
keytool -genkey -alias democompany2 -keyalg RSA -keystore democompany2_keystore.jks
keytool -certreq -alias democompany2 -keyalg RSA -file democompany2.csr -keystore democompany2_keystore.jks
Signing the user CSRWith the CA configured you can sign a CSR request with this command:
openssl ca -config openssl.my.cnf -policy policy_anything -out certs/democompany2.crt -infiles democompany2.csr
Configuring server: Glassfish domain.xml The default Glassfish V2.1 server configuration does not have the truststore password properly configured. It is probably intentional since you should change the truststore pass for all the systems you run Glassfish on anyway. So to make things work you have to tell Glassfish it's truststore password by adding this to the JVM commands in domain.xml:
<jvm-options>-Djavax.net.ssl.trustStorePassword=changeit</jvm-options>
You also have to configure Glassfish auth realm so that it knows wich groups you want to authenticate with user certificates. So do this in your domain.xml :
(existing) <auth-realm classname="com.sun.enterprise.security.auth.realm.certificate.CertificateRealm" name="certificate">
(add this) <property name="assign-groups" value="TESTGROUP"/>
(existing) </auth-realm>
Configuring server: Glassfish truststoreYou have to import the CA cert to your glassfish truststore so that the server will trust your signed certificates. You can do this with the keytool like this:
keytool -import -v -alias myCA -file certs/myca.crt -storepass changeit -keystore /Users/erkulas/apps/glassfish-v2.1-b60e/domains/domain1/config/cacerts.jks
Running server: an JAX-WS example webserviceThis is a sample webservice configuration.
application.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE application PUBLIC "-//Sun Microsystems, Inc.//DTD J2EE Application 1.3//EN" "http://java.sun.com/dtd/application_1_3.dtd">
<application>
<display-name>security-Example-sslApp</display-name>
<module>
<web>
<web-uri>Esample-web.war</web-uri>
<context-root>ExampleWS</context-root>
</web>
</module>
</application>
sun-application.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sun-application PUBLIC "-//Sun Microsystems, Inc.//DTD Sun ONE Application Server 8.0 J2EE Application 1.4//EN" "http://www.sun.com/software/sunone/appserver/dtds/sun-application_1_4-0.dtd">
<sun-application>
<security-role-mapping>
<role-name>TESTGROUP</role-name>
<group-name>TESTGROUP</group-name>
</security-role-mapping>
</sun-application>
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:j2ee="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.5"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<servlet-name>Example</servlet-name>
<servlet-class>ws.Example</servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Example</servlet-name>
<url-pattern>/Example</url-pattern>
</servlet-mapping>
<login-config>
<auth-method>TESTGROUP</auth-method>
</login-config>
<security-role>
<role-name>TESTGROUP</role-name>
</security-role>
<security-constraint>
<web-resource-collection>
<web-resource-name>Secure Area</web-resource-name>
<url-pattern>/</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
<http-method>HEAD</http-method>
<http-method>PUT</http-method>
<http-method>OPTIONS</http-method>
<http-method>TRACE</http-method>
<http-method>DELETE</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>TESTGROUP</role-name>
</auth-constraint>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
</web-app>
ws.Example.java:
package ws;
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.WebParam;
import javax.xml.ws.WebServiceContext;
@javax.jws.WebService(targetNamespace = "")
public class Example {
@Resource
WebServiceContext wsContext;
@WebMethod
public String sampleEcho(@WebParam(name = "sampleParamStr", targetNamespace = "") String sampleParamStr ) throws java.lang.Exception
{
// sample of getting the principal (cert data) from messagecontext
MessageContext mx = wsContext.getMessageContext();
Subject subb = (Subject)( mx.get("CLIENT_SUBJECT") );
Object[] principals = subb.getPrincipals().toArray();
Principal principal = (Principal)principals[1];
String name = principal.getName();
// return input string as a result
ret = sampleParamStr;
return ret;
}
}