Java Dynamic Management Kit 5.1 Tutorial

11.2 Subject Delegation

If your implementation requires the client end of the connection to perform different operations on behalf of multiple users or applications, if you were to use the security mechanisms demonstrated in 11.1 Simple Security, each different user would require one secure connection for every operation it performs. If you expect your connector clients to interact with numerous users, you can reduce the load on your system by implementing subject delegation. Subject delegation establishes a single secure connection for a user, and this connection can be used to perform related operations on behalf of any number of users. The connection itself is made by an authenticated user. If the authenticated user has been granted a SubjectDelegationPermission that allows it to act on behalf of another user, then operations can be performed over the connection on behalf of that user.

11.2.1 Secure RMI Connectors With Subject Delegation

You can find an example of a secure RMI connector that implements subject delegation in the directory examplesDir/current/Security/rmi/subject_delegation.

The Server class used in this example is identical to the one used in 11.1 Simple Security. However, unlike the simple security example, this example implements a java.policy file to grant permission to certain users to perform certain actions.


Example 11–5 A java.policy File

grant codeBase "file:installDir/lib/jmxremote.jar" {
    permission javax.management.remote.SubjectDelegationPermission 
             "javax.management.remote.JMXPrincipal.delegate";
};

grant codeBase "file:server" {
    permission javax.management.remote.SubjectDelegationPermission 
              "javax.management.remote.JMXPrincipal.delegate";
};

grant principal javax.management.remote.JMXPrincipal "username" {
     permission javax.management.remote.SubjectDelegationPermission 
              "javax.management.remote.JMXPrincipal.delegate";
};

The java.policy file grants a user named username a SubjectDelegationPermission so it can perform operations on behalf of the user delegate, an instance of JMXPrincipal created by the Client class. The java.policy file is required when launching the Server class. The creation of the JMXPrincipal instance by the Client is shown below.


Example 11–6 Creating a Delegation Subject

[...]

JMXConnector jmxc = JMXConnectorFactory.connect(url, env); 
Subject delegationSubject = 
            new Subject(true, 
                Collections.singleton(new JMXPrincipal("delegate")), 
                Collections.EMPTY_SET, 
                Collections.EMPTY_SET); 
 
MBeanServerConnection mbsc = 
          jmxc.getMBeanServerConnection(delegationSubject); 
[...]

The Client class is identical to the one used in the simple security example, except for the creation of the delegation subject shown in Example 11–6.

As before, the Client creates an environment map env that is populated with a user name username and a password password. These strings match the user name and password stored in the password.properties file that is held by the Server to authenticate users accessing the connector server.

A connector client jmxc is created in the same way as in the previous RMI connector examples, with the user name and password passed into the environment map env.

The Client then creates an instance of Subject, called delegationSubject, with a Principal that is an instance of JMXPrincipal, named delegate.

An MBean server connection, named mbsc, is created by calling the getMBeanServerConnection() method of JMXConnector, with delegationSubject passed in as a parameter. This MBean server connection therefore allows operations to be performed on the remote MBean server on behalf of the principals stored in the delegationSubject, which in this example is the JMXPrincipal named delegate.

The example continues by creating and registering the SimpleStandard MBean in the MBean server, and performing operations on it, in exactly the same way as in the previous examples.

To Run the Secure RMI Connector Example With Subject Delegation

Run this example from within the examplesDir/current/Security/rmi/subject_delegation directory.

  1. Compile the example classes.


    $ javac -classpath classpath \ 
      mbeans/SimpleStandard.java \ 
      mbeans/SimpleStandardMBean.java \ 
      server/Server.java \ 
      client/Client.java \ 
      client/ClientListener.java 
    
  2. Start an RMI registry on port 9999 of the local host.


    $ export CLASSPATH=server:classpath ; rmiregistry 9999 &
    
  3. Create a java.policy file from the java.policy.template file in the config directory.

    You must replace @INSTALL_HOME_FOR_JDMK@ with your installDir.

  4. Start the Server.

    As was the case with the simple secure RMI connector example, you have to provide the SSL keystore and its password when you start the Server, as well as the a pointer to the java.policy that grants permission to the delegate subject.


    $ java -classpath server:mbeans:classpath \
         -Djavax.net.ssl.keyStore=config/keystore \
         -Djavax.net.ssl.keyStorePassword=password \
         -Djava.security.policy=config/java.policy Server &
    

    You will see confirmation of the creation of the MBean server, the initialization of the environment map, the creation of the RMI connector, and the registration of the connector in the MBean server.

  5. Start the Client.

    Again, the Client requires the SSL truststore and its password when it is launched.


    $ java -classpath client:server:mbeans:classpath \
         -Djavax.net.ssl.trustStore=config/truststore \
         -Djavax.net.ssl.trustStorePassword=trustword \
         Client
    

    You will see confirmation of the creation of the connector client, the creation of the delegation subject, the connection to the MBean server and the various MBean operations followed by the closure of the connection.

11.2.2 Secure JMXMP Connectors With Subject Delegation

The example of JMXMP connectors with subject delegation is mostly identical to the example of a simple secure JMXMP connector. The only differences are in the client end of the connection, in which the delegation subject is defined, and in the java.policy file used to grant permission to the delegation subjects created.

In this example, the Server class creates an MBean server, and a connector server cs, again protected by an SSL password, as was the case in the simple secure JMXMP connector example.

The Client creates a connector client named jmxc in the same way as in the previous JMXMP connector examples. The Client then creates an instance of Subject, called delegationSubject, with a Principal that is an instance of JMXPrincipal, named delegate.

An MBean server connection, named mbsc, is created by calling the getMBeanServerConnection() method of JMXConnector, with delegationSubject passed in as a parameter. This MBean server connection therefore allows operations to be performed on the remote MBean server on behalf of the principals stored in the delegationSubject, which in this example is the JMXPrincipal named delegate.

To Run the Secure JMXMP Connector Example With Subject Delegation

Run this example from within the examplesDir/current/Security/jmxmp/subject_delegation directory.

  1. Compile the example classes.


    $ javac -classpath classpath \
          mbeans/SimpleStandard.java \
          mbeans/SimpleStandardMBean.java \
          server/Server.java \
          server/PropertiesFileCallbackHandler.java \
          client/Client.java \
          client/ClientListener.java \
          client/UserPasswordCallbackHandler.java
    
  2. Create a java.policy file from the java.policy.template file in the config directory.

    You must replace @INSTALL_HOME_FOR_JDMK@ with your installDir.

  3. Start the Server.

    The Server requires the SSL keystore file and its password, and a pointer to the java.policy file when you launch it.


    $ java -classpath server:mbeans:classpath \
         -Djavax.net.ssl.keyStore=config/keystore \
         -Djavax.net.ssl.keyStorePassword=password \
         -Djava.security.policy=config/java.policy Server &
    

    You will see confirmation of the creation of the MBean server, the initialization of the environment map and the launching of the JMXMP connector.

  4. Start the Client.

    Again, the Client requires the SSL truststore and its password when it is launched.


    $ java -classpath client:mbeans:classpath \
         -Djavax.net.ssl.trustStore=config/truststore \
         -Djavax.net.ssl.trustStorePassword=trustword \
         Client
    

    You will see confirmation of the creation of the JMXMP connector client, the initialization of the environment map, the creation of the delegation subject, the connection to the MBean server and the performance of the various MBean operations followed by the closure of the connection.