For security concern, I decide to add in JMX authentication. It is very complicated to setup with Java's configuration. However, I managed to do so with Spring with two simple steps:
1. CustomJMXAuthenticator.java
package com.my.company.server;
import javax.management.remote.JMXAuthenticator;
import javax.management.remote.JMXPrincipal;
import javax.security.auth.Subject;
import org.apache.commons.lang.StringUtils;
/**
* @author Yaohua Wang
*
*/
public class CustomJMXAuthenticator implements JMXAuthenticator {
private String userName;
private String password;
public void setUserName(String userName) {
this.userName = userName;
}
public void setPassword(String password) {
this.password = password;
}
public Subject authenticate(Object credentials) {
if(credentials == null
|| !(credentials instanceof String[]))
throw new SecurityException("Credentials are required!");
String[] info = (String[]) credentials;
if(StringUtils.equals(info[0], userName)
&& StringUtils.equals(info[1], password)){
Subject subject = new Subject();
subject.getPrincipals().add(new JMXPrincipal(userName));
return subject;
}
throw new SecurityException("Unable to match credentials!");
}
}
2. Spring configuration:
<bean id="registry"
class="org.springframework.remoting.rmi.RmiRegistryFactoryBean"
destroy-method="destroy" autowire="no">
<property name="port" value="1099"/>
<property name="alwaysCreate" value="true"/>
</bean>
...
<bean id="serverConnector" class="org.springframework.jmx.support.ConnectorServerFactoryBean" autowire="no" depends-on="registry">
<property name="objectName" value="connector:name=rmi"/>
<property name="serviceUrl"
value="service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi"/>
<property name="threaded" value="true"/>
<property name="daemon" value="true"/>
<property name="environmentMap">
<map>
<entry key="java.rmi.server.hostname" value="localhost"/>
<entry key="jmx.remote.authenticator">
<bean
class="com.my.company.server.CustomJMXAuthenticator">
<property name="userName" value="jmxuser"/>
<property name="password" value="jmxpassword"/>
</bean>
</entry>
</map>
</property>
</bean>
Now start the server and open jconsole. Type in following information:
- Remote Process: localhost:1099
- User Name: jmxuser
- Password: jmxpassword