all.
Have been trying to get remoted JMX with JAAS authentication to work usin Camel version 2.10.3 + Java 6.
The app uses Java DSL and is "hand wired", and runs with system properties:
-Dcom.sun.management.jmxremote.authenticate=true
-Djmx.remote.x.login.config=StagingJmxAuthConfig
-Dorg.apache.camel.jmx.usePlatformMBeanServer=true
-Djava.security.auth.login.config=./src/main/resources/conf/ldap-auth.config
-Dcom.sun.management.jmxremote.ssl=false
-Dorg.apache.camel.jmx.createRmiConnector=true
-Dorg.apache.camel.jmx.rmiConnector.registryPort=9140
However, for all intents and purposes it seems that I might as well be running with authentication/authorization switched off.
Debugging into the JRE's JMX and JAAS classes (and Camel as well), note the following:
In the class org.apache.camel.management.DefaultManagementAgent
:
cs = JMXConnectorServerFactory.newJMXConnectorServer(url, null, server);
This in turn later creates an instance of javax.management.remote.rmi.RMIJRMPServerImpl
with an empty Map for the env
constructor argument.
Now, I wonder if there's something that's just escaping me -- when a request later comes to the the connector, and the javax.management.remote.rmi.RMIServerImpl
does a doNewClient()
, it can't possibly trigger any JAAS activity?
Line 197-208 of RMIServerImpl - remember Camel sets "env" to null
, which is translated to empty map:
JMXAuthenticator authenticator =
(JMXAuthenticator) env.get(JMXConnectorServer.AUTHENTICATOR);
if (authenticator == null) {
/*
* Create the JAAS-based authenticator only if authentication
* has been enabled
*/
if (env.get("jmx.remote.x.password.file") != null ||
env.get("jmx.remote.x.login.config") != null) {
authenticator = new JMXPluggableAuthenticator(env);
}
}
Am I correct in assuming that to get remoted, JAAS authenticated JMX to work one must hand code the JMX RMI connector setup?
Shouldn't Camel have provided an environment to get JAAS to work? Doesn't even seem to touch the JAAS config file...
UPDATE: SOLVED
Setting the following system properties on the VM did the trick:
-Dcom.sun.management.jmxremote=true
-Dcom.sun.management.jmxremote.port=9410
-Dcom.sun.management.jmxremote.authenticate=true
-Djmx.remote.x.login.config=StagingJmxAuthConfig
-Dorg.apache.camel.jmx.usePlatformMBeanServer=true
-Djava.security.auth.login.config=./src/main/resources/conf/ldap-auth.config
-Dcom.sun.management.jmxremote.ssl=false
-Dorg.apache.camel.jmx.createRmiConnector=false
-Dcom.sun.management.jmxremote.login.config=StagingJmxAuthConfig
For us, using a secured LDAP, the following is the login config:
StagingJmxAuthConfig {
com.sun.security.auth.module.LdapLoginModule REQUIRED
java.naming.security.authentication="simple"
java.naming.security.principal="cn=Directory Manager"
java.naming.security.credentials="PASSWORD"
userProvider="ldap://LDAPHOST:389/BASEDN"
userFilter="(&(uid={USERNAME})(appRole=SOME_VALUE))"
authzIdentity=monitorRole
debug=true
useSSL=false;
};
Now I'm able to connect using jmxterm:
java -jar jmxterm-1.0-alpha-4-uber.jar -l service:jmx:rmi:///jndi/rmi://THEHOST:9410/jmxrmi -u LDAPUSER -p LDAPPASS
Note that the JNDI RMI name is missing the "/camel" postfix -- this is the only difference, it seems.
HOORAY!
In essence:
The example above also shows how to connect to a search protected LDAP, which is actually isolated as the application in question uses a different LDAP for JNDI lookup for JMS.