23 詳細なセキュリティ
JMX APIは、接続を保護するために既存のセキュリティ・プロトコルを使用します。この例では、詳細なセキュリティの実装を提供します。この項に含まれるソース・コードを使用して、適切な設定手順で指定したexamples/
ディレクトリに対応するファイルが作成され、次の内容が含まれます。
警告:
セキュリティ・マネージャおよびそれに関連するAPIは非推奨であり、今後のリリースでは削除されます。セキュリティ・マネージャの代わりとなるものはありません。詳細および代替手段については、JEP 411を参照してください。-
README file
-
Server
-
Client
-
ClientListener
-
keystore
-
password.properties
-
truststore
-
java.policy
-
SimpleStandard
-
SimpleStandardMBean
examples/Security/fine_grained/README
# ==============================================================================
#
# Example of a secure RMI connector (using Security Manager and Policy File).
#
# This example uses:
#
# - the RMI SSL socket factories for encryption,
# - the password authenticator based on the JMXAuthenticator interface for
# user authentication,
# - the JAAS and the J2SE Security Architecture based on the use of security
# managers and policy files for user access level authorization.
#
# ==============================================================================
#
# In order to compile and run the example, make a copy of this README file, and
# then simply cut and paste all the commands as needed into a terminal window.
#
# This README makes the assumption that you are running under Java SE 6 on Unix,
# you are familiar with the JMX technology, and with the bourne shell or korn
# shell syntax.
#
# All the commands below are defined using Unix korn shell syntax.
#
# If you are not running Unix and korn shell you are expected to be able to
# adapt these commands to your favorite OS and shell environment.
#
# Compile Java classes
#
# * Server.java: creates an MBeanServer and creates and starts a secure RMI
# connector server (JRMP).
#
# * Client.java: creates a secure RMI connector (JRMP), creates and registers
# a Simple standard MBean and performs operations on it.
#
# * ClientListener.java: implements a generic notification listener.
#
# * SimpleStandard.java: implements the Simple standard MBean.
#
# * SimpleStandardMBean.java: the management interface exposed by the Simple
# standard MBean.
#
javac mbeans/SimpleStandard.java \
mbeans/SimpleStandardMBean.java \
server/Server.java \
client/Client.java \
client/ClientListener.java
# Start the RMI registry:
#
export CLASSPATH=server ; rmiregistry 9999 &
# Start the Server:
#
java -classpath server:mbeans \
-Djavax.net.ssl.keyStore=config/keystore \
-Djavax.net.ssl.keyStorePassword=password \
-Djava.security.manager \
-Djava.security.policy=config/java.policy \
Server &
# Start the Client:
#
java -classpath client:server:mbeans \
-Djavax.net.ssl.trustStore=config/truststore \
-Djavax.net.ssl.trustStorePassword=trustword \
Client
# ==============================================================================
examples/Security/fine_grained/server/Server.java
import java.io.File;
import java.util.HashMap;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
import javax.management.remote.rmi.RMIConnectorServer;
import javax.rmi.ssl.SslRMIClientSocketFactory;
import javax.rmi.ssl.SslRMIServerSocketFactory;
public class Server {
public static void main(String[] args) {
try {
// Instantiate the MBean server
//
System.out.println("\nCreate the MBean server");
MBeanServer mbs = MBeanServerFactory.createMBeanServer();
// Environment map
//
System.out.println("\nInitialize the environment map");
HashMap env = new HashMap();
// Provide SSL-based RMI socket factories.
//
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);
// Provide the password file used by the connector server to
// perform user authentication. The password file is a properties
// based text file specifying username/password pairs. This
// properties based password authenticator has been implemented
// using the JMXAuthenticator interface and is passed to the
// connector through the "jmx.remote.authenticator" property
// in the map.
//
// This property is implementation-dependent and might not be
// supported by all implementations of the JMX Remote API.
//
env.put("jmx.remote.x.password.file",
"config" + File.separator + "password.properties");
// Create an RMI connector server
//
System.out.println("\nCreate an RMI connector server");
JMXServiceURL url = new JMXServiceURL(
"service:jmx:rmi:///jndi/rmi://localhost:9999/server");
JMXConnectorServer cs =
JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs);
// Start the RMI connector server
//
System.out.println("\nStart the RMI connector server");
cs.start();
System.out.println("\nRMI connector server successfully started");
System.out.println("\nWaiting for incoming connections...");
} catch (Exception e) {
e.printStackTrace();
}
}
}
examples/Security/fine_grained/client/Client.java
import java.util.HashMap;
import javax.management.Attribute;
import javax.management.JMX;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
public class Client {
public static void main(String[] args) {
try {
// Environment map
//
System.out.println("\nInitialize the environment map");
HashMap env = new HashMap();
// Provide the credentials required by the server to successfully
// perform user authentication
//
String[] credentials = new String[] { "username" , "password" };
env.put("jmx.remote.credentials", credentials);
// Create an RMI connector client and
// connect it to the RMI connector server
//
System.out.println("\nCreate an RMI connector client and " +
"connect it to the RMI connector server");
JMXServiceURL url = new JMXServiceURL(
"service:jmx:rmi:///jndi/rmi://localhost:9999/server");
JMXConnector jmxc = JMXConnectorFactory.connect(url, env);
// Get an MBeanServerConnection
//
System.out.println("\nGet an MBeanServerConnection");
MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();
// Get domains from MBeanServer
//
System.out.println("\nDomains:");
String domains[] = mbsc.getDomains();
for (int i = 0; i < domains.length; i++) {
System.out.println("\tDomain[" + i + "] = " + domains[i]);
}
// Create SimpleStandard MBean
//
ObjectName mbeanName = new ObjectName("MBeans:type=SimpleStandard");
System.out.println("\nCreate SimpleStandard MBean...");
mbsc.createMBean("SimpleStandard", mbeanName, null, null);
// Get MBean count
//
System.out.println("\nMBean count = " + mbsc.getMBeanCount());
// Get State attribute
//
System.out.println("\nState = " +
mbsc.getAttribute(mbeanName, "State"));
// Set State attribute
//
mbsc.setAttribute(mbeanName,
new Attribute("State", "changed state"));
// Get State attribute
//
// Another way of interacting with a given MBean is through a
// dedicated proxy instead of going directly through the MBean
// server connection
//
SimpleStandardMBean proxy = JMX.newMBeanProxy(
mbsc, mbeanName, SimpleStandardMBean.class);
System.out.println("\nState = " + proxy.getState());
// Add notification listener on SimpleStandard MBean
//
ClientListener listener = new ClientListener();
System.out.println("\nAdd notification listener...");
mbsc.addNotificationListener(mbeanName, listener, null, null);
// Invoke "reset" in SimpleStandard MBean
//
// Calling "reset" makes the SimpleStandard MBean emit a
// notification that will be received by the registered
// ClientListener.
//
System.out.println("\nInvoke reset() in SimpleStandard MBean...");
mbsc.invoke(mbeanName, "reset", null, null);
// Sleep for 2 seconds in order to have time to receive the
// notification before removing the notification listener.
//
System.out.println("\nWaiting for notification...");
Thread.sleep(2000);
// Remove notification listener on SimpleStandard MBean
//
System.out.println("\nRemove notification listener...");
mbsc.removeNotificationListener(mbeanName, listener);
// Unregister SimpleStandard MBean
//
System.out.println("\nUnregister SimpleStandard MBean...");
mbsc.unregisterMBean(mbeanName);
// Close MBeanServer connection
//
System.out.println("\nClose the connection to the server");
jmxc.close();
System.out.println("\nBye! Bye!");
} catch (Exception e) {
e.printStackTrace();
}
}
}
examples/Security/fine_grained/client/ClientListener.java
import javax.management.Notification;
import javax.management.NotificationListener;
public class ClientListener implements NotificationListener {
public void handleNotification(Notification notification, Object handback) {
System.out.println("\nReceived notification: " + notification);
}
}
examples/Security/fine_grained/config/password.properties
# password.properties
# Password file for Remote JMX API authentication. This file defines
# the different roles and their passwords.
# The file format for the password file is syntactically the same as
# the Properties file format. The syntax is described in the JavaDoc page
# for java.util.Properties.load.
# A typical password file has multiple lines, where each line is blank,
# a comment (like this one), or a password entry.
# A password entry consists of a role name and an associated password.
# The role name is any string that does not itself contain spaces or
# tabs. The password is again any string that does not contain spaces
# or tabs. Note that passwords appear in the clear in this file, so it
# is a good idea not to use valuable passwords.
# A given role should have at most one entry in this file. If a role
# has no entry, it has no access.
# If multiple entries are found for the same role name, then the last
# one is used.
# In a typical installation, this file can be read by anybody on the
# local machine, and possibly by people on other machines.
# For security, you should either restrict the access to this file,
# or specify another, less accessible file in the management config
# file as described above.
# Role and password used for authentication by the RMI connector in
# this example.
#
username password
examples/Security/fine_grained/config/java.policy
grant codeBase "file:server" {
//
// The server requires the permissions to create and register the connector
// and all the permissions required by the operations performed by remote
// user calls. Here AllPermission is granted for simplicity.
//
permission java.security.AllPermission;
};
grant codeBase "file:mbeans" {
permission javax.management.MBeanTrustPermission "register";
};
grant principal javax.management.remote.JMXPrincipal "username" {
permission javax.management.MBeanPermission "*", "getDomains";
permission javax.management.MBeanPermission "SimpleStandard#-[-]", "instantiate";
permission javax.management.MBeanPermission "SimpleStandard#-[MBeans:type=SimpleStandard]", "registerMBean";
permission javax.management.MBeanPermission "SimpleStandard#State[MBeans:type=SimpleStandard]", "getAttribute";
permission javax.management.MBeanPermission "SimpleStandard#State[MBeans:type=SimpleStandard]", "setAttribute";
permission javax.management.MBeanPermission "SimpleStandard#-[MBeans:type=SimpleStandard]", "addNotificationListener";
permission javax.management.MBeanPermission "SimpleStandard#reset[MBeans:type=SimpleStandard]", "invoke";
permission javax.management.MBeanPermission "SimpleStandard#-[MBeans:type=SimpleStandard]", "removeNotificationListener";
permission javax.management.MBeanPermission "SimpleStandard#-[MBeans:type=SimpleStandard]", "unregisterMBean";
//
// This permission is only required for the authenticated user and not for the delegated users.
//
// The RMI connector client registers a listener on the MBeanServerDelegate to control the MBean
// creation/deletion. The listener is removed when the connection to the server is closed.
//
permission javax.management.MBeanPermission "javax.management.MBeanServerDelegate#-[JMImplementation:type=MBeanServerDelegate]", "addNotificationListener";
permission javax.management.MBeanPermission "javax.management.MBeanServerDelegate#-[JMImplementation:type=MBeanServerDelegate]", "removeNotificationListener";
};
examples/Security/fine_grained/mbeans/SimpleStandard.java
/**
* Simple definition of a standard MBean, named "SimpleStandard".
*
* The "SimpleStandard" standard MBean shows how to expose attributes
* and operations for management by implementing its corresponding
* "SimpleStandardMBean" management interface.
*
* This MBean has two attributes and one operation exposed
* for management by a JMX agent:
* - the read/write "State" attribute,
* - the read only "NbChanges" attribute,
* - the "reset()" operation.
*
* This object also has one property and one method not exposed
* for management by a JMX agent:
* - the "NbResets" property,
* - the "getNbResets()" method.
*/
import javax.management.AttributeChangeNotification;
import javax.management.MBeanNotificationInfo;
import javax.management.NotificationBroadcasterSupport;
public class SimpleStandard
extends NotificationBroadcasterSupport
implements SimpleStandardMBean {
/*
* -----------------------------------------------------
* CONSTRUCTORS
* -----------------------------------------------------
*/
/* "SimpleStandard" does not provide any specific constructors.
* However, "SimpleStandard" is JMX compliant with regards to
* contructors because the default contructor SimpleStandard()
* provided by the Java compiler is public.
*/
/*
* -----------------------------------------------------
* IMPLEMENTATION OF THE SimpleStandardMBean INTERFACE
* -----------------------------------------------------
*/
/**
* Getter: get the "State" attribute of the "SimpleStandard" standard MBean.
*
* @return the current value of the "State" attribute.
*/
public String getState() {
return state;
}
/**
* Setter: set the "State" attribute of the "SimpleStandard" standard MBean.
*
* @param <VAR>s</VAR> the new value of the "State" attribute.
*/
public void setState(String s) {
state = s;
nbChanges++;
}
/**
* Getter: get the "NbChanges" attribute of the "SimpleStandard" standard
* MBean.
*
* @return the current value of the "NbChanges" attribute.
*/
public int getNbChanges() {
return nbChanges;
}
/**
* Operation: reset to their initial values the "State" and "NbChanges"
* attributes of the "SimpleStandard" standard MBean.
*/
public void reset() {
AttributeChangeNotification acn =
new AttributeChangeNotification(this,
0,
0,
"NbChanges reset",
"NbChanges",
"Integer",
new Integer(nbChanges),
new Integer(0));
state = "initial state";
nbChanges = 0;
nbResets++;
sendNotification(acn);
}
/*
* -----------------------------------------------------
* METHOD NOT EXPOSED FOR MANAGEMENT BY A JMX AGENT
* -----------------------------------------------------
*/
/**
* Return the "NbResets" property.
* This method is not a Getter in the JMX sense because it
* is not exposed in the "SimpleStandardMBean" interface.
*
* @return the current value of the "NbResets" property.
*/
public int getNbResets() {
return nbResets;
}
/**
* Returns an array indicating, for each notification this MBean
* may send, the name of the Java class of the notification and
* the notification type.</p>
*
* @return the array of possible notifications.
*/
public MBeanNotificationInfo[] getNotificationInfo() {
return new MBeanNotificationInfo[] {
new MBeanNotificationInfo(
new String[] { AttributeChangeNotification.ATTRIBUTE_CHANGE },
AttributeChangeNotification.class.getName(),
"This notification is emitted when the reset() method is called.")
};
}
/*
* -----------------------------------------------------
* ATTRIBUTES ACCESSIBLE FOR MANAGEMENT BY A JMX AGENT
* -----------------------------------------------------
*/
private String state = "initial state";
private int nbChanges = 0;
/*
* -----------------------------------------------------
* PROPERTY NOT ACCESSIBLE FOR MANAGEMENT BY A JMX AGENT
* -----------------------------------------------------
*/
private int nbResets = 0;
}
examples/Security/fine_grained/mbeans/SimpleStandardMBean.java
/**
* This is the management interface explicitly defined for the
* "SimpleStandard" standard MBean.
*
* The "SimpleStandard" standard MBean implements this interface
* in order to be manageable through a JMX agent.
*
* The "SimpleStandardMBean" interface shows how to expose for management:
* - a read/write attribute (named "State") through its getter and setter
* methods,
* - a read-only attribute (named "NbChanges") through its getter method,
* - an operation (named "reset").
*/
public interface SimpleStandardMBean {
/**
* Getter: set the "State" attribute of the "SimpleStandard" standard
* MBean.
*
* @return the current value of the "State" attribute.
*/
public String getState();
/**
* Setter: set the "State" attribute of the "SimpleStandard" standard
* MBean.
*
* @param <VAR>s</VAR> the new value of the "State" attribute.
*/
public void setState(String s);
/**
* Getter: get the "NbChanges" attribute of the "SimpleStandard" standard
* MBean.
*
* @return the current value of the "NbChanges" attribute.
*/
public int getNbChanges();
/**
* Operation: reset to their initial values the "State" and "NbChanges"
* attributes of the "SimpleStandard" standard MBean.
*/
public void reset();
}