Contents | Previous | Next Java Management Extensions (JMX) Technology Tutorial

Chapter   5

Security

This chapter gives examples of how to set up the JMX technology security features, as described in the following sections:

  • Section  "Simple Security" presents examples of connectors that implement straightforward security based on password authentication and file access control.
  • Section  "Subject Delegation" presents examples of connectors that use the subject delegation model to perform operations on a given authenticated connection on behalf of several different identities.
  • Section  "Fine-Grained Security" presents examples of connectors that implement more sophisticated security mechanisms, in which permission to perform individual operations is controlled.

Caution: Applications should prompt the user to enter passwords rather than expecting the user to provide them on the command line. Use secure authentication mechanisms in production systems.

Simple Security

The simplest type of security you can use with the JMX technology is based upon encryption, user name and password authentication, and file access control.

RMI Connectors With Simple Security

You can find an example of an RMI connector with simple security in the directory work_dir/jmx_examples/Security/simple.

  1. Open the work_dir/jmx_examples/Security/simple directory.

    Inside this directory you will find the following directories:

    • /server, containing the fileServer.java
    • /config, containing the security configuration files:
    • access.properties
    • keystore
    • password.properties
    • truststore
    • /mbeans, containing the following files:
    • SimpleStandardMBean.java
    • SimpleStandard.java
    • /client, containing the following files:
    • Client.java
    • ClientListener.java
  2. Open all the *.java and *.properties files in a text editor

    These files will be analyzed in the following sections.

Server.java

The Server.java class is shown in CODE EXAMPLE 5-1.

CODE EXAMPLE 5-1 RMI Connector Example (Simple Security) Class Server.java
 
public class Server { 
 
  public static void main(String[] args) { 
  try { 
       MBeanServer mbs = MBeanServerFactory.createMBeanServer(); 
 
       HashMap env = new HashMap(); 
 
       SslRMIClientSocketFactory csf =  
                  new SslRMIClientSocketFactory(); 
       SslRMIServerSocketFactory ssf =  
                  new SslRMIServerSocketFactory(); 
       env.put(RMIConnectorServer. 
                  RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE,csf); 
       env.put(RMIConnectorServer. 
                  RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE,ssf); 
 
       env.put("jmx.remote.x.password.file", 
                 "config" + File.separator + "password.properties"); 
       env.put("jmx.remote.x.access.file", 
                 "config" + File.separator + "access.properties"); 
 
       JMXServiceURL url = new JMXServiceURL( 
        "service:jmx:rmi:///jndi/rmi://localhost:9999/server"); 
         JMXConnectorServer cs = 
            JMXConnectorServerFactory.newJMXConnectorServer(url,  
                                                            env,  
                                                            mbs); 
       cs.start(); 
     } catch (Exception e) { 
       e.printStackTrace(); 
     } 
  } 
} 
 

The Server class shown in CODE EXAMPLE 5-1 creates an MBean server mbs, and populates an environment map env with a secure RMI client socket factory csf, a secure RMI server socket factory ssf, and the properties files password.properties and access.properties.

The properties file password.properties contains a username and password and is accessed using the JMX Remote API interface JMXAuthenticator. Using the property jmx.remote.x.password.file is the same as creating a password-based JMXAuthenticator and passing it into the environment map through the jmx.remote.authenticator property.

The properties file access.properties contains a username and a level of access permission that can be either readwrite or readonly. This represents the level of access this user can have to MBean server operations. This file-based access control is implemented using the JMX technology interface MBeanServerForwarder, which wraps the real MBean server inside an access controller MBean server. The access controller MBean server only forwards requests to the real MBean server after performing the appropriate checks.

Server creates a JMX service URL, named url, for an RMI connector that will operate over the default JRMP transport, and register an RMI connector stub in an RMI registry on port 9999 of the local host.

The MBean server mbs, the environment map env and the service URL url are all passed to JMXConnectorServer to create a new, secure JMX connector server named cs.

SimpleStandardMBean.java

The SimpleStandardMBean class defines the same straightforward MBean interface as was used in Chapter 3, "JMX Connectors".

SimpleStandard.java

The SimpleStandard class defines the same straightforward MBean as was used in Chapter 3, "JMX Connectors".

ClientListener.java

The ClientListener class defines the same straightforward notification listener as was used in Chapter 3, "JMX Connectors".

Client.java

The Client.java class is shown in CODE EXAMPLE 5-1.

CODE EXAMPLE 5-1 RMI Connector Example (Simple Security) Class Client.java
 
public class Client { 
 
  public static void main(String[] args) { 
  try { 
      HashMap env = new HashMap(); 
 
      String[] credentials = new String[] { "username" , "password" }; 
      env.put("jmx.remote.credentials", credentials); 
      JMXServiceURL url = new JMXServiceURL( 
         "service:jmx:rmi:///jndi/rmi://localhost:9999/server");       
      JMXConnector jmxc = JMXConnectorFactory.connect(url, env); 
      MBeanServerConnection mbsc = jmxc.getMBeanServerConnection(); 
      String domains[] = mbsc.getDomains(); 
      for (int i = 0; i < domains.length; i++) { 
         System.out.println("Domain[" + i + "] = " + domains[i]); 
      } 
       
      ObjectName mbeanName =  
          new ObjectName("MBeans:type=SimpleStandard"); 
      mbsc.createMBean("SimpleStandard", mbeanName, null, null); 
      // Perform MBean operations 
      [...] 
      
      mbsc.removeNotificationListener(mbeanName, listener); 
      mbsc.unregisterMBean(mbeanName); 
      jmxc.close(); 
    }  catch (Exception e) { 
      e.printStackTrace(); 
    } 
  } 
} 
 

The Client class shown in CODE EXAMPLE 5-1 populates an environment map env with a set of credentials, namely the username and password expected by the Server. These credentials are then given to an instance of JMXConnector named jmxc when the service URL of the connector stub and the environment map are passed to JMXConnectorFactory.connect(). Through jmxc, the Client connects to the MBean server started by Server, and performs MBean operations.

When the connection is established, the credentials supplied in the environment map env are sent to the server. The server then calls the authenticate() method of the JMXAuthenticator interface, passing the client credentials as parameters. The authenticate() method authenticates the client and returns a subject that contains the set of principals upon which the access control checks will be performed.

Running the RMI Connector Example With Simple Security

To run the RMI connector example with simple security, perform the following steps:


Copyright © 1993, 2014, Oracle and/or its affiliates. All rights reserved.