WebService|mutual way ssl certificate with coding and installation
Using JAX-WS-Based Web Services with SSL |
This Tech Tip reprinted with permission by java.sun.com In Java EE 5, a web service that is based on JAX-WS can be implemented either as an EJB endpoint or servlet endpoint. An example of a JAX-WS-based web service implemented as an EJB endpoint is provided in the Tech Tip Developing Web Services Using EJB 3.0. A JAX-WS-based web service implemented as a servlet endpoint is provided in the Tech Tip Developing Web Services Using JAX-WS. Irrespective of the way a web service is implemented, most enterprise applications, including those that use web services, need to run in asecure environment. Transport Layer Security (TLS)/Secure Sockets Layer (SSL) is a point-to-point secure transport mechanism that can be used for authentication, message integrity, and confidentiality. TLS/SSL (or in this tip, simply "SSL") meets the security requirements of most enterprise application environments, and is widely adopted. This Tech Tip shows you how to construct a JAX-WS-based web service that runs with SSL, and how to access the web service from an application client. A sample package accompanies the Tech Tip. It demonstrates a Java client accessing a JAX-WS web service using SSL. Examples are provided for web services implemented as EJB and servlet endpoints. The sample uses an open source reference implementation of Java EE 5 called GlassFish. You can download GlassFish from the GlassFish Community Downloads page. Write the Class for the Web Service Endpoint Let's begin by writing a Java class for the web service. SSL has no impact on the Java code for the web service endpoint. The same code works for web services that use SSL or that don't use SSL. In Java EE 5, you can use annotations to easily construct a JAX-WS web service. Here's an example of a web service implemented as an EJB endpoint:
The @Stateless annotation marks the class as a stateless session bean, and the @WebService annotation marks the class as a web service. The @Resource annotation is used to declare resource dependencies that the class has -- in essence, what resources the class needs. These resources are then injected into the endpoint implementation. In this example, the annotation identifies a resource dependency on the WebServiceContext. The class needs the WebServiceContext to get context information about requests, such as related security information. Here's the same web service implemented as a servlet endpoint:
Specify Security Information in Deployment Descriptors To use SSL in a web service that is implemented as an EJB endpoint, you need to specify security information in a vendor-specific deployment descriptor (in this tip, sun-ejb-jar.xml). For a web service implemented as a servlet, you need to specify the security information in the web.xml descriptor. One important aspect of secure communication through SSL is server authentication, that is, confirming the identity of the server to the client. Another aspect is client authentication, where the server confirms the identity of the client. In SSL, you can have either server authentication or the combination of server and client authentication (but not client authentication alone). This tip uses the term "mutual authentication" to mean the combination of server and client authentication. (Note however that other documents might attach a different meaning to mutual authentication. For example, in some documents, the term client authentication is synonymous with mutual authentication.) To enable SSL server authentication, you need to set the <transport-guarantee> element to CONFIDENTIAL. For a web service implemented as an EJB endpoint, you set the element in the sun-ejb-jar.xml deployment descriptor. For a web service implemented as a servlet, you set the element in the web.xml deployment descriptor. As an example, for the HelloEjb web service, the <transport-guarantee> element in the sun-ejb-jar.xml deployment descriptor should look this:
For the HelloServletService service, the <transport-guarantee> element web.xml deployment descriptor should look like this:
Notice the <http-method> element value of POST in web.xml. JSR-109, "Implementing Enterprise Web Services", specifies that the service endpoint authorization must be defined using an http-method element value of POST. In GlassFish, WSDL files are protected by SSL for endpoints with SSL or SSL mutual authentication. For SSL mutual authentication, you need to set the <auth-method> subelement of the <login-config> element to CLIENT-CERT. You also need to set the <transport-guarantee> element to CONFIDENTIAL. For instance, in sun-ejb-jar.xml;
No deployment descriptor is needed for the client program. Package and Deploy the Web Service Application Packaging and deploying a web service application that uses SSL is the same as for a web service application that doesn't use SSL. Keep in mind however, that if the web service is implemented as a servlet endpoint in an enterprise archive (that is, a .ear file), you need to include the application.xml file to specify the context-root for the web application. Write the Client After deploying the web service, you can access it from a client program. The client program for a web service application that uses SSL is essentially the same as one that doesn't use SSL. The major difference is that instead of using HTTP as the internet protocol, you need to use HTTPS. In the client, you use the @WebServiceRef annotation to declare a reference to a web service. The value of the wsdlLocation parameter in @WebServiceRef is a URL that points to the location of the WSDL file for the service being referenced. So for a web service client that uses SSL, the wsdlLocation parameter in the @WebServiceRef annotation needs to specify an HTTPS URL. For example: @WebServiceRef(wsdlLocation= "https://serverName:8181/HelloEjbService/HelloEjb?WSDL") private static HelloEjbService helloEjbService; You can then access the port for the web service and invoke the web service: HelloEjb helloEjbPort = helloEjbService.getHelloEjbPort(); helloEjbPort.hello("Hello World"); Client-side artifacts are generated by accessing the WSDL file through HTTPS. To do that, you need to specify the location of a truststore file for the server and its password in the environment variable VMARGS. In SSL, you can use certificates to authenticate the server or for mutual authentication of both the server and client. The truststore file for the server contains the trusted certificates for the server and its keys. You can specify the location of the server's truststore file and its password in various ways, for example, you can specify them in an ant script as follows:
Set Up the Client Truststore and Keystore In addition to a truststore file for the server, you also need a truststore file for the client. The client validates the server certificate against a set of certificates in its truststore. For a secure connection to be made using SSL, the client-side truststore needs to trust the server certificate. For SSL mutual authentication, the server-side truststore also needs to trust the client certificate. If you modify the server-side truststore, you need to restart the server (this allows use of the new certificate). You might not need to do this in a production environment because production certificates are signed by a common Certificate Authority (CA). The GlassFish builds include certificates for several common root CAs. For SSL mutual authentication, you need to provide your own key in a client keystore (a file that contains the client's keys and certificates). You can use keytool, a key and certificate management utility in JDK 5.0, to generate the keystore. Run the Client Before you run the client that access a web service with SSL, you need to set the value of the environment variable, VMARGS. After that, you can run the application as usual. For SSL, set the value of VMARGS to: -Djavax.net.ssl.trustStore=${truststore.location} -Djavax.net.ssl.trustStorePassword=${ssl.password} For SSL mutual authentication, set the value of VMARGS to: -Djavax.net.ssl.trustStore=${truststore.location} -Djavax.net.ssl.trustStorePassword=${ssl.password} -Djavax.net.ssl.keyStore =${keystore.location} -Djavax.net.ssl.keyStorePassword=${ssl.password} Running the Sample Code To install and run the sample code that accompanies this tip:
Add $JAVA_HOME/bin, $ANT_HOME/bin, and $GLASSFISH_HOME/bin to your PATH environment variable. keytool -list -v -alias s1as -keystore $GLASSFISH_HOME/domains/domain1/config/cacerts.jks In response, you'll be prompted for a keystore password. Respond with the default password, changeit. You can change the password. ant setup This creates a private key in a local keystore, exports the certificate, and imports it to the common truststore. Note that a self-signed certificate is installed in the truststore. This is for testing purposes only and is not recommended for production. $GLASSFISH_HOME/bin/asadmin stop-domain domain1 Then start it: $GLASSFISH_HOME/bin/asadmin start-domain domain1 This picks up the new certificate in the truststore. ant build This compiles the EJB and Servlet Web Services classes and creates an ear file. Then enter the command: ant deploy This deploys the ear file in GlassFish. And finally, the following command: ant build-client This generates artifacts and compiles the client-side code. ant run You should see results that look something like this: [exec] Retrieving port from the service ejbws.HelloEjbService@4e21db [exec] Invoking hello operation on the HelloEjbService port [exec] Ejb WS: CN=serverName, OU=SSLClient, O=EJTechTips, L=Santa Clara, ST=California, C=US: Hello World [exec] Retrieving port from the service servletws.HelloServletService@ea7549 [exec] Invoking hello operation on the HelloServletService port [exec] Servlet WS: CN=serverName, OU=SSLClient, O=EJTechTips, L=Santa Clara, ST=California, C=US: Hello World You can see additional information, such as information about the SSL handshake, by adding jvm option -Djavax.net.debug=ssl,handshake. You can do this for the sample by entering the following command: ant run-debug You can verify that this is an SSL mutual authentication by looking at the CertificateRequest during handshake. If you want to see more debugging information, use the jvm option -Djavax.net.debug=all. ant undeploy ant unsetup $GLASSFISH_HOME/bin/asadmin stop-domain domain1 $GLASSFISH_HOME/bin/asadmin start-domain domain1 About the Author Shing Wai Chan is a senior member of the Sun Java Application Server and Java EE SDK development teams. He has been focusing on development projects that relate to security, annotations, CMP, B2B and B2C. Copyright (c) 2004-2005 Sun Microsystems, Inc. |
2 comments:
It's nice information...I got the SSL certificate here http://www.xnynz.com/ It provides hosting,domain name register, domain appraisal, online file folder, ssl certificate etc...
With many not understanding the impact Java has on SSL Certificates and encryption this holds some valuable information. My SSL provider SSL247.co.uk also provided me with the technical support and assistance I needed for this. But this is a great complimentary piece so thanks for posting!
Post a Comment