Question

I have a JMX server configured without Spring and am trying to implement Spring Security for the Authorization part. (See here, https://blogs.oracle.com/lmalventosa/entry/jmx_authentication_authorization Use Case 4, without the Authorization part)

I would like now to implement the Authorization part using Spring Security.

In my JMX authenticator, I do:

final List<GrantedAuthority> roles = new ArrayList<GrantedAuthority>();
roles.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
final Authentication auth = new UsernamePasswordAuthenticationToken(credentialsArr[0], credentialsArr[1],
                        roles);
SecurityContextHolder.getContext().setAuthentication(auth);

And in the MBeans I try to fetch it and see that it has been passed correctly (in the future I plan to add Spring Annotations to check for roles, for method invocation).

final Authentication springAuth = SecurityContextHolder.getContext().getAuthentication();

The problem is, that in the standard connection flow:

JMXServiceURL url = ...;
Map env = ...;
String[] creds = {"monitorRole", "mrpasswd", "FileRealm"};
env.put(JMXConnector.CREDENTIALS, creds);
JMXConnector cc = JMXConnectorFactory.connect(url, env);
MBeanServerConnection mbsc = cc.getMBeanServerConnection();

I get a JMX connector, then connect to the MBean server and invoke a method - it works. I get through the authenticator, set the Spring Context and get it in the Mbean.

But when I connect using a Jconsole, for example, I don't get the Spring Context in the Mbean.

I am using the Inheritable Thread strategy.

  1. Is there a way to get the context also in the MBean, when connecting using the JConsole and other connectors?
  2. If I implement JMX using Spring, will it help me to solve the problem?
  3. Is my main flow fool proof (is there a chance I will not get the Context in the MBean)? I am asking this, since this flow is critical to me, to be fool proof.

Thanks a lot!

Was it helpful?

Solution

I will answer my own question, as I've seen interest in it and wanted to share my own conclusions (unrelated to the numbers above):

  1. It looks like connecting with JConsole(or JVisualVM) locally (i.e. to localhost) connects directly to the thread, without going through the JMX Authenticator. The only workaround I found was by connecting with a full URL (e.g. service:jmx:rmi:///jndi/rmi://10.45.32.112:3251/jmxrmi).

  2. One mechanism that works always is the Java Security context; when JMXAuthenticator returns a Subject, you may assign the Spring Security Context to it and thus surely get it when invoking the method (e.g. in an Advice running before the invocation). See this reply I got: http://forum.springsource.org/showthread.php?134327-JMX-Authentication-with-Spring-Security-%283-1-x%29

  3. I can't say for sure if the flow mentioned in the question is fool proof. But it seems like it is, based on this assumption: If you create a new connection for each JMX call and use it only for one invocation, you will get the Spring Security Context to propagate correctly.

Hope it helped you people :-)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top