Monday Feb 18, 2008

Web Services Connector for JMX enters Public Review

The JSR 262 has just entered the Public Review phase. The Early Access 3 of the Connector, that implements the Public Review, can be downloaded from http://ws-jmx-connector.dev.java.net.

Specification changes since Early Access 2:

  • PUSH mode supported for notifications. This is specified in the client by including JMXWSDefinitions.JMX_WS_NOTIFICATION_PUSH_MODE_URL in the Map given to JMXConnectorFactory.connect. Some related Map entries on the client and server configure security. A new interface JMXWSCredentialsProvider specifies how the connector server gets the credentials it needs to connect to any given client and push notifications.

  • New JMX types supported for MBean operations: NotificationResult, NotificationFilterSupport, AttributeChangeNotificationFilter, MBeanServerNotificationFilter. This allows the JSR 262 connector to support the new Event Service being defined by JSR 255, which has MBean operations that use those types. We also added support for java.lang.Enum and java.util.Set.

  • Connection identifiers supported consistently with the JMX Remote API (JSR 160) specification. This was already alluded to in the Early Draft 2 but is now formalized consistently.

  • Removed the interface JMXWSManResourceHandler. This was a halfway house between the Connector and Adaptor models. The model now is that for a Connector (client sees the JMX Remote API), the protocol is completely specified and invariable.

  • Some minor reshuffling of static final fields between JMXWSConnectorServer and JMXWSDefinitions.

  • The getMBeanInfo operation is now mapped as a Custom Action. Previously the MBeanInfo was a property of the MBean resource, alongside all the attributes of the MBean. This mix of data and metadata was strange.

  • JMXAuthenticator.authenticate method. The passed Object parameter used to be a String[2]. It is now a String[3]. The third element contains a client certificate in case HTTPS Mutual authentication is enabled (null otherwise).

  • XML Element NotificationLost has been removed from the schema. WS-Management already offers such definition by the mean of DroppedEvents XML element. NotificationLost was a redundant redefinition.

  • The schema has been updated, mostly to reflect the changes above, and some minor refactoring.

Implementation changes since Early Access 2:

  • Leverage of the Metro stack components (as detailed in my previous blog entry) in order to increase interoperability and efficiency of the Connector. We are currencly observing a \*3 increase in performance.

  • Rely on the latest JAX-WS 2.1.3 release.

  • Introduction of an adaptor API that allows you to change the way MBeans are exposed in the WS-Management world (javadoc is bundled in the Early Access 3 auto extractible jar under docs directory).

The document that covers interoperability with Microsoft WinRM tooling (winrm command line, VBScript API and Event Viewer support for WS-Management events) has been updated in order to reflect the Public Review changes.

Feedbacks on the specification can be sent to jsr262-spec-comments@sun.com. Feedbacks on the connector implementation can be sent to users@ws-jmx-connector.dev.java.net.

Thanks.

Jean-Francois Denise

Thursday Aug 16, 2007

Securing JMX Web Services Connector


I have been contacted by a customer of the JSR 262 Early Access 2 who asked me for some material on how to enable HTTPS. I realized that no material was provided. No sample, no blog entry, nothing... Why is there such a lack of documentation? Thinking at it, it appeared that the extreme simplicity of enabling HTTPS for the WS Connector made us forget to provide material for it. This blog entry is trying to correct that and highlight the extreme simplicity enabling HTTPS.

Here, I will present in turn a JDK 5 and a JDK 6 example. The scenario is very common. You have already written a JMX agent and a JMX client. You have already tested that all your JMX MBeans are working well. It is now deployment time! And it is at this precise time that your customer asks you for Security...
You never thought that it could happen to you. You know that security is a complex topic. Encryption, symmetric or asymmetric keys are things that you have heard of but you prefer to stay away from them...
No worries, the JMX WebServices Connector takes charge of all the details. You are just required to configure it. So let's start by securing your ConnectorServer.

Securing the ConnectorServer

Your agent code looks something like :
  JMXConnectorServer server =
                JMXConnectorServerFactory.
                newJMXConnectorServer(new JMXServiceURL("service:jmx:ws:" +
                "//localhost:8080/jmxws"), null,
                ManagementFactory.getPlatformMBeanServer());

  server.start();

Right? This is the very classical way to start a JMX Connector. If this is not the case, if the way you create and start your agent is not similar to this code, please send me a mail (jean-francois dot denise at sun dot com)

So how do you enable HTTPS? Simply by changing the protocol name when creating the JMXServiceURL to be ws-secure instead of ws.

So now your code looks like :
  JMXConnectorServer server =
                JMXConnectorServerFactory.
                newJMXConnectorServer(new JMXServiceURL("service:jmx:ws-secure:" +
                "//localhost:8080/jmxws"), null,
                ManagementFactory.getPlatformMBeanServer());

  server.start();

Are you done? Not yet, you need to provide a KeyStore location and a KeyStore password for SSL to find the certificates. You don't have a KeyStore or a certificate? Not a big deal, use keytool! For example call :

keytool -genkey -keystore jsr262Keystore -keyalg RSA

Answer the questions and provide a KeyStore password. In this blog entry I am using 123456 as the password value. This is something that you should never do in a real context. In this blog entry context, however, is is safe enough.
keytool generates a file named jsr262Keystore. You have now a KeyStore that contains a certificate secured by a password.
If you are running JDK 6, it is enough to actually launch your JMX agent in a secure way. The keyStore and password are provided thanks to two standard Java properties. For example :

java -classpath ... -Djavax.net.ssl.keyStore=jsr262Keystore -Djavax.net.ssl.keyStorePassword=123456 MyJMXAgent

Simple, no? Yes, but what about if I am using JDK 5? Why isn't it so simple?
Simply because JDK 6 has been extended to support a default SSL configuration that relies on the Java properties we previously used (javax.net.ssl.keyStore and javax.net.ssl.keyStorePassword). On JDK 5, you need to provide an instance of javax.net.ssl.SSLContext. Here, I provide you with an SSLContext that reads the standard Java properties in order to compute an SSL configuration. You can use this TestSSLContext Java file that implements the required logic.

How do I pass this SSLContext to the WS ConnectorServer? By using the env map when calling the JMXConnectorServerFactory class.
Your updated source code looks like :
        // Create the SSLContext
         SSLContext ctx = TestSSLContext.getInstance("SSLv3");
        // Create an env map
        Map env = new HashMap(1);
        // Provide the SSLContext
        env.put("jmx.remote.ws.sslcontext", ctx);
        // Create the ConnectorServer providing the env map
        JMXConnectorServer server =
                JMXConnectorServerFactory.
                newJMXConnectorServer(new JMXServiceURL("service:jmx:ws-secure:" +
                "//localhost:8080/jmxws"), env,
                ManagementFactory.getPlatformMBeanServer());
        
        server.start();

You are done, you can start your JMX Agent the same way you did using JDK 6.

java -classpath ... -Djavax.net.ssl.keyStore=jsr262Keystore -Djavax.net.ssl.keyStorePassword=123456 MyJMXAgent

You have now a JMX agent running, waiting for https requests. Let's go secure the client side.

Securing the Connector

This is JDK 5 or 6 independent. You need to replace the ws protocol name with ws-secure as you did on the server side, then provide a TrustStore location and password. The KeyStore named jsr262KeyStore we previously created can be reused by the client.
Your client code looks something like :
 JMXServiceURL url = new JMXServiceURL("service:jmx:ws://localhost:8080/jmxws");
 JMXConnector connector = JMXConnectorFactory.connect(url, null);
 //Get the MBeanServerConnection
 MBeanServerConnection mbsc = connector.getMBeanServerConnection();

Once the JMXServiceURL value has been updated, you code looks like:
 JMXServiceURL url = new JMXServiceURL("service:jmx:ws-secure://localhost:8080/jmxws");
 JMXConnector connector = JMXConnectorFactory.connect(url, null);
 //Get the MBeanServerConnection
 MBeanServerConnection mbsc = connector.getMBeanServerConnection();

When starting the client you provide the TrustStore and password using two standard Java properties. For example :

java -classpath ... -Djavax.net.ssl.trustStore=jsr262Keystore -Djavax.net.ssl.trustStorePassword=123456 MyClient

And... you are done! Extremely simple, no? I hope so, otherwise, let me know ;-).

Some material

Here is all the material I created to write this blog entry. A first NetBeans project containing the source of the agent, the source of TestSSLContext (remember, this is only needed on JDK 5) and the jsr262KeyStore. A second NetBeans project containing the source of the client. You will have to correct some references (mainly JDK, JAX-WS libraries) when opening them but they can help you start securing your app.

Next blog entry to come? Why not use WS-Security (Security applied to the SOAP message) to secure JMX Web Services communication. Stay tuned.

Regards.

Jean-Francois
About

jeanfrancoisdenise

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today