Wednesday September 05, 2007 In a previous post, Securing JMX Web Services Connector, I explained how to enable HTTPS when using the JSR 262 RI. Basic Authentication and HTTPS are the basic building blocks on which you can rely to secure remote WS access to your JMX instrumentation. These technologies are very commonly used and are simple to put in place when you need point-to-point security. For more complex architectures, however, where messages contexts contain multiple nodes, HTTPS is not the best solution.
WS-Security, a Web Services standard defined by OASIS, aims to secure communication at the SOAP message level (as opposed to HTTPS, that secures messages at the transport level) in a unified, flexible and extensible way. WS-Security supports partial message signing and encryption, in case you need to encrypt the SOAP message body element and keep the headers non-encrypted; for example, when encrypting credit card numbers or any XML subtrees.
In addition to confidentiality and authentication (also offered by HTTPS + Basic Authentication), WS-Security offers message integrity, thanks to XML signatures. With XML signatures, you can protect your communication against message-tampering.
Due to the huge number of alternatives you can use when trying to secure your communications, you will generally run into interoperability problems. WS-Security has been designed to offer interoperability while still allowing you to plug in various technologies. The WSIT project on java.net (JavaOne 2007 Technical Session TS-4865 offers a good introduction to WSIT) offers an interoperable WS-* stack that, along with a full set of other WS standards, integrates a Java technology implementation of WS-Security. WSIT is the solution I have adopted to plug WS-Security into the Connector.
Now that we have briefly introduced WS-Security and WSIT, let's go back to what really interests us, namely plugging WS-Security into the Web Services Connector. The XWSS project, that is part of WSIT, offers everything we need to enable WS-Security in our context. How is this achieved? Simply because the JMX Connector is a JAX-WS Web Service (compliant with WS-Management but still a classical JAX-WS Web Service) and XWSS works well with JAX-WS.
So, I started by reading a XWSS article on how to add WS-Security to your Web Services on top of the Java SE 6 platform.
I then adapted the XWSS sample application to create a simple JMX client and server. I interacted with Kumar Jayanti from the XWSS team to get our two
technologies working well together. We encountered some issues with WSIT Milestone 6 (mainly related to the fact that WS-Policy was still linked to a Java EE platform type of deployment, and the JMX Connector
was being deployed on the Java SE platform), but these have been fixed in the latest WSIT builds. The next WSIT FCS Milestone should contain all the necessary fixes.
The usage of WS-Policy makes for a transparent usage of WS-Security. If you package your
WS-Security configuration files properly, you can enable WS-Security on the client side and on the server side without touching a single line of code (see the next section for full details of how to make this work).
To enable WS-Security you simply need to package your application with the WSIT binaries and the WS-Security configuration file.
Main.java into the src/simplejdk6ws/ directory. The ConnectorServer is started on port 8080. In case of conflict, update the Main.java file (be sure to update the client code accordingly, see the next section for the client side).SimpleWSClient.java into the src/simplejdk6ws/ directory. The Connector connects to port 8080. In case of conflict, update the SimpleWSClient.java file (it should follow the value you previously provided when starting the server).
This client application is a very simple one, it connects to the server and asks for the Default Management domain (MBeanServerConnection.getDefaultDomain()).src/META-INF/server_security_config.xml. Any message received and response sent is Authenticated, Signed and Encrypted according to the configuration defined in this configuration file.
You don't need to update this file.src/META-INF/client_security_config.xml. Any message sent and response received is Authenticated (user Ron), Signed and Encrypted according to the configuration defined in this configuration file.
Again, you don't need to update this file.java -jar jax-ws-latest-wsit-installer_nightly.jarThe
jax-ws-latest-wsit directory is created.endorsed. Move jax-ws-latest-wsit/lib/webservices-api.jar into this directory.java -jar jsr262-ri.jarThe
jsr262-ri directory is created.src directory and type the following command:javac -cp :../endorsed/webservices-api.jar:../jax-ws-latest-wsit/lib/webservices-rt.jar simplejdk6ws/*.java
src directory. The command should be something similar to the following:
java -cp .:../mail-1.4.jar:../jsr262-ri/lib/jmxws.jar:../jsr262-ri/lib/wiseman-core.jar:../jax-ws-latest-wsit/lib/webservices-rt.jar -Djava.endorsed.dirs=../endorsed/ simplejdk6ws.MainYou should see the following message:
JSR 262 ConnectorServer is ready to serve on http://localhost:8080/jmxws
src directory. The command should be something similar to the following: java -cp .:../mail-1.4.jar:../jsr262-ri/lib/jmxws.jar:../jsr262-ri/lib/wiseman-core.jar:../jax-ws-latest-wsit/lib/webservices-rt.jar -Djava.endorsed.dirs=../endorsed/ simplejdk6ws.SimpleWSClientYou should observe a very verbose output containing the secured received and sent SOAP messages. You will notice that the user Ron never appears in the messages, because the user name is encrypted. At the end, the Default Management domain will be displayed.
When a request is received, the JMX WS Connector Server looks for the existence of Principals in order to create a javax.security.auth.Subject that will be used to
check the Java platform's permissions. XWSS, after having dealt with Security, creates a Subject that contains all the authenticated principals (X500 certificate, Trusted user, etc.).
XWSS makes this Subject accessible thanks to the call SubjectAccessor.getRequesterSubject(context). This call is XWSS-implementation-dependent
and other WS-Security implementations are likely to offer their own way. This is why we have added a hook to plug a Subject extractor into the ConnectorServer to retrieve the Subject
and make it accessible to the ConnectorServer.
The following XWSSSecuritySubjectExtractor class is an example of such an XWSS-aware SubjectExtractor:
class XWSSSecuritySubjectExtractor extends JMXWSSubjectExtractor {
protected Subject getExtraSubject(WebServiceContext context) {
try {
return SubjectAccessor.getRequesterSubject(context);
} catch (XWSSecurityException ex) {
ex.printStackTrace();
}
return null;
}
}
|
To pass the extractor instance to the ConnectorServer, use the environment map :
Map
|
This is the updated Main.java file that contains the Subject Extractor.
WARNING: You need the updated JMX WS Connector RI jmxws.jar and wiseman-core.jar file to use the SubjectExtractor API. You can download these jars here.
Call java -jar jsr262-patch-ws-security.jar to extract the jmxws.jar and wiseman-core.jar files.
When compiling the agent, add both JAR files to your classpath.
So, if one day you reach the limits of the capabilities of HTTPS + Basic Authentication, you should think about using WS-Security.
I hope that I have demonstrated to you that enabling it is straightforward. But you should be aware that enabling WS-Security will significantly impact the performance of the WS Connector.
The time needed to check security added to the time needed to create and parse a secured SOAP Message (here is an example of a AUTH+PRIV+SIGN getDefaultDomain response SOAP message) makes for much slower client/server interaction.
Enjoy and have fun.
Jean-Francois
A. Sundararajan
Alan Bateman
Daniel Fuchs
Éamonn McManus
Joël Féraud
Mandy Chung
Luis-Miguel Alventosa