Page 1 of 2 12 LastLast
Results 1 to 10 of 18

Thread: How to secure jmxServer (JConsole)

  1. #1
    Join Date
    Jun 2009
    Posts
    2

    Default How to secure jmxServer (JConsole)

    I have been trying to secure the JConsole access to my stand-alone Java Server which uses Spring 2.5, but it seems anyone that knows the URL and jmx port can access JConsole without being challenged for login credentials. The Sun docs say that by default authentication is enabled, but it seems not.

    http://java.sun.com/j2se/1.5.0/docs/...tml#connecting

    Anyway, I have been trying to secure it via spring-jmx-config.xml, since providing JVM parms when launching the server has no effect. Am I on the right track or can somebody tell me what I am doing wrong? The doc says if you give it a non-existent password location you will not have access, but JConsole continues to be wide open...

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
    <beans>
    <bean class="org.springframework.remoting.rmi.RmiRegistr yFactoryBean">
    <property name="port" value="17999"/>
    </bean>

    <bean id="jmxServer" class="org.springframework.jmx.support.ConnectorSe rverFactoryBean">
    <property name="serviceUrl" value="service:jmx:rmi://localhost/jndi/rmi://localhost:17999/Pipeline"/>
    <property name="registrationBehaviorName" value="REGISTRATION_REPLACE_EXISTING"/>
    <property name="environmentMap">
    <map>
    <entry key="com.sun.management.jmxremote.authenticate" value-ref="true"/>
    <entry key="com.sun.management.jmxremote.password.file" value-ref="foo"/>
    </map>
    </property>

    </bean>

    <bean id="mbeanExporter" class="org.springframework.jmx.export.MBeanExporte r">
    ....
    </bean>

    </beans>

    Thanks in advance to anyone who can point me in the right direction.

  2. #2
    Join Date
    Aug 2006
    Posts
    130

    Default JMXAuthenticator

    i had the same issue and i've found out by implementing JMXAuthenticator the most flexible way to secure jconsole and authenticate via spring security :

    config :

    Code:
    <util:constant id="jmx.auth.attribute" static-field="javax.management.remote.JMXConnectorServer.AUTHENTICATOR"/>
    
    <bean id="jmx.authenticator" class="wims.cycle.jmx.JmxSecurityAuthenticator"/>
    
    <util:map id="jmx.environment">
    		<entry key-ref="jmx.auth.attribute" value-ref="jmx.authenticator"/>
    	</util:map>
    
    <bean id="jmx.server" class="org.springframework.jmx.support.MBeanServerFactoryBean"
    		p:locateExistingServerIfPossible="false"/>
    
    <bean id="jmx.server.connector" class="org.springframework.jmx.support.ConnectorServerFactoryBean" depends-on="jmx.registry"
    		p:server-ref="jmx.server"
    		p:objectName="connector:name=rmi"
    		p:serviceUrl="service:jmx:rmi://localhost/jndi/rmi://localhost:1099/cycle"
    		p:environmentMap-ref="jmx.environment"
    />
    JMXAuthenticator :

    Code:
    public class JmxSecurityAuthenticator implements JMXAuthenticator{
    
    	@Resource
    	private AuthenticationManager authMgr;
    
    	public Subject authenticate(Object credentials) {
    		try{
    			String[] info = (String[]) credentials;
    			
    			Authentication auth = authMgr.authenticate(new UsernamePasswordAuthenticationToken(info[0],info[1]));
    			
    			
    			Subject s = new Subject();
    			s.getPrincipals().add(new JMXPrincipal(auth.getName()));
    			return s;
    		}catch(Exception e){
    			throw new SecurityException(e);
    		}
    	}
    
    }

  3. #3
    Join Date
    Jun 2009
    Posts
    2

    Default ConnectorServerFactoryBean environment map properties

    I tried the JMXAuthenticator approach which was posted, but it seems the poster is using a version of Spring different than 2.5? I am getting errors on the environment map properties for ConnectorServerFactoryBean. Does anyone know where these properties are documented? I am not seeing them documented anywhere...

  4. #4
    Join Date
    Aug 2006
    Posts
    130

    Default

    which errors ?

    i've used JMXAuthenticator against
    spring pre-2.5 era , spring 2.5 till 2.5.6 and post-2.5 (current 3.0.0.M3)

  5. #5
    Join Date
    Aug 2006
    Posts
    130

    Default

    Doc says :
    The secure JMX server will be running on port 9998.
    so should this be
    service:jmx:rmi:///jndi/rmi://localhost:9998/JMXSecureConnector ?
    or is the connector opened at port 1099 ?

  6. #6

    Default

    Here is some info on my experience with getting the authentication part to work...

    In case any one else was confused about what "p:" namespace prefix refers to here is a useful ref:

    http://blog.springsource.com/2006/11...-in-spring-20/

    You will need to declare both the "util:" and "p:" namespace in the bean config file. Here is what eventually worked for me after much trial and error...

    Code:
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:security="http://www.springframework.org/schema/security"
           xmlns:util="http://www.springframework.org/schema/util"
           xmlns:p="http://www.springframework.org/schema/p"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schem...-beans-2.0.xsd
                               http://www.springframework.org/schema/security http://www.springframework.org/schem...curity-2.0.xsd
           http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">
        
    
        <!-- JXM Authentication -->
        <util:constant id="jmx.auth.attribute" static-field="javax.management.remote.JMXConnectorServer.AUTHENTICATOR"/>
    
        <bean id="jmx.authenticator" class="my.impl.package.JMXAuthenticatorImpl">
            <property name="authManager" ref="_authenticationManager"/>
        </bean>
    
        <util:map id="jmx.environment">
            <entry key-ref="jmx.auth.attribute" value-ref="jmx.authenticator"/>
        </util:map>
    
        <bean id="jmx.server" class="org.springframework.jmx.support.MBeanServerFactoryBean"
                        p:locateExistingServerIfPossible="true"/>
    
        <bean id="jmx.server.connector" class="org.springframework.jmx.support.ConnectorServerFactoryBean" depends-on="jmx.registry"
                        p:server-ref="jmx.server"
                        p:objectName="connector:name=rmi"
                        p:serviceUrl="service:jmx:rmi://localhost/jndi/rmi://localhost:1099/jmxRMIConnector"
                        p:environmentMap-ref="jmx.environment"
        />
    
        <!-- Needed to declare the following -->
        <bean id="jmx.registry" class="org.springframework.remoting.rmi.RmiRegistryFactoryBean">
            <property name="port" value="1099"/>
        </bean>
    
    </beans>
    Last edited by farrukh_najmi; Feb 28th, 2011 at 02:45 PM.

  7. #7

    Default How to do authorization for an authenticated JMX operation?

    I was able to get JMX Authentication working with spring-security using spring-core 3.0.5.RELEASE (see previous message). However, I am still working to figure out how I can get the Authentication object when a @ManagedAttribute is set via a JMX Client like jvisualvm. I need this to determine authorization and access control. Does any one have any suggestions on how I can get the Authentication object when my @ManagedAttribute setter is called from an authenticated JMX client?

  8. #8

    Default

    I have gotten Authorization to work as follows...

    • Use SecurityContextHolder.getContext().setAuthenticati on(auth); in the JMXAuthenticatorImpl.authenticate method
    • In JMX ManagedOperations that require authorization use SecurityContextHolder.getContext().getAuthenticati on(); to get the AUthentication object and then use it for authorization


    I found that sometimes the SecurityContextHolder.getContext().getAuthenticati on(); returns null initially (perhaps because server was still booting). Once server was in steady state it seemed to work fine and return an Authentication object.

  9. #9

    Default

    Quote Originally Posted by farrukh_najmi View Post
    I found that sometimes the SecurityContextHolder.getContext().getAuthenticati on(); returns null initially (perhaps because server was still booting). Once server was in steady state it seemed to work fine and return an Authentication object.
    Actually I am seeing the SecurityContextHolder.getContext().getAuthenticati on(); return null more often than not. This leads me to believe that the JMX authentication thread (where SecurityContextHolder.getContext().setAuthenticati on(); is called) and the JMX operation thread (where SecurityContextHolder.getContext().getAuthenticati on(); is called) are not the same typically.

    What I learned is that one MUST NOT save the authenticated JMX Connection within jvisualvm or else the authentication happens automatically when you start jvisualvm and it is in a separate thread than the subsequent JMX secure operation. As long as you create a new authenticated JMX Connection each time you start jvisualvm then the authentication happens in same thread as subsequent JMX operation. It is obviously very brittle to use ThreadLocal mechanism such as SecurityContextHolder.getContext().authentication.

    Is there a better way?
    Last edited by farrukh_najmi; Mar 3rd, 2011 at 10:25 AM.

  10. #10
    Join Date
    Aug 2006
    Posts
    130

    Default authorization

    store authentication :

    Code:
    public Subject authenticate(Object credentials) {
    		try{
    			Authentication authentication = authMgr.authenticate(getAuthentication(credentials));
    			registry.register(authentication.getName(), authentication);
    			return getSubject(authentication);
    		}catch(AuthenticationException e){
    			logger.warn(e);
    			throw new SecurityException(e);
    		}
    	}
    set a delegatingmbean or use aop :

    Code:
    <aop:config>
     			<aop:pointcut id="jmx-pointcut" expression="execution(public * javax.management.MBeanServer.invoke(..))" />
     			<aop:aspect ref="jmx-security-handler">
     				<aop:around  pointcut-ref="jmx-pointcut" method="invoke"/>
     			</aop:aspect>
     		</aop:config>
    lookup authentication info :

    Code:
    public Object invoke(ProceedingJoinPoint pjp) throws Throwable{
    		try{
    			SecurityContextHolder.getContext().setAuthentication(lookup());
    			return pjp.proceed();
    		}finally{
    			SecurityContextHolder.clearContext();
    			if (logger.isDebugEnabled()) {
                    logger.debug("Cleared SecurityContextHolder.");
                }
    		}
    	}
    
    private Authentication lookup(){
    		try{
             	return registry.get(lookup(Subject.getSubject(AccessController.getContext())));
    		}catch(Exception e){
    			logger.warn(e.getMessage());
    		}
    		return null;
    	}
    	
    	private String lookup(Subject subject){
    		return subject.getPrincipals(JMXPrincipal.class).iterator().next().getName();
    	}
    Last edited by wims.tijd; Mar 4th, 2011 at 06:51 AM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •