Version 7

    Using XMBean Deployments for Security

    An advantage of the XMBean deployment model is that custom interceptors can be used to introduce aspects like security. XMBeans are an early variant of the JBossAOP aspect container.

     

    The following XMBean descriptor illustrates how the standard jboss JNDI NamingServer can be deployed with security added via custom interceptors.  Add these lines to $JBOSS_HOME/server/<Profile>/conf/xmdesc/NamingService-xmbean.xml as shown below:

    <!ATTLIST interceptor securityDomain CDATA #IMPLIED>
    
    <interceptor code="org.jboss.test.jmx.interceptors.JNDISecurity"
         securityDomain="secure-jndi"></interceptor>
    <interceptor code="org.jboss.naming.interceptors.ProxyFactoryInterceptor"
         proxyName="jboss:service=proxyFactory,type=jrmp,target=Naming"></interceptor>

     

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mbean PUBLIC
       "-//JBoss//DTD JBOSS XMBEAN 1.1//EN"
       "http://www.jboss.org/j2ee/dtd/jboss_xmbean_1_1.dtd"
    [
       <!ATTLIST interceptor proxyName CDATA #IMPLIED>
       <!ATTLIST interceptor securityDomain CDATA #IMPLIED>
    ]>
    
    <!-- The JNDI Naming service XMBean
    $Id: NamingService-xmbean.xml,v 1.1.2.2 2004/10/10 04:30:19 starksm Exp $
    -->
    <mbean>
       <description>The standard JBoss JNDI naming server with a custom
          ProxyFactoryInterceptor interceptor that does replacement of NamingContext
          objects with the detached invoker proxy.
       </description>
    
       <descriptors>
          <interceptors>
             <!-- for JBoss 3.2.x securityDomain="java:/jaas/secure-jndi" -->
             <interceptor code="org.jboss.test.jmx.interceptors.JNDISecurity"
                securityDomain="secure-jndi"></interceptor>
             <interceptor code="org.jboss.naming.interceptors.ProxyFactoryInterceptor"
                proxyName="jboss:service=proxyFactory,type=jrmp,target=Naming"></interceptor>
             <interceptor code="org.jboss.mx.interceptor.PersistenceInterceptor2" ></interceptor>
             <interceptor code="org.jboss.mx.interceptor.ModelMBeanInterceptor" ></interceptor>
             <interceptor code="org.jboss.mx.interceptor.ObjectReferenceInterceptor" ></interceptor>
          </interceptors>
       </descriptors>
    
       <class>org.jboss.naming.NamingService</class>
    
       <constructor>
          <description>The default constructor</description>
          <name>NamingService</name>
       </constructor>
       
       &defaultAttributes;
    
       <attribute access="read-only" getMethod="getMethodMap">
          <name>MethodMap</name>
          <type>java.util.Map</type>
       </attribute>
       <attribute access="read-write" getMethod="getCallByValue" setMethod="setCallByValue">
          <description>The call by value mode. true if all lookups are unmarshalled using
          the caller's TCL, false if in VM lookups return the value by reference.</description>
          <name>CallByValue</name>
          <type>boolean</type>
       </attribute>
       <attribute access="read-write" getMethod="getBindAddress" setMethod="setBindAddress">
          <description>The bind address of the bootstrap lookup socket.</description>
          <name>BindAddress</name>
          <type>java.lang.String</type>
       </attribute>
       <attribute access="read-write" getMethod="getPort" setMethod="setPort">
          <description>The listening port for the bootstrap JNP service. Set this to -1
            to run the NamingService without the JNP invoker listening port.</description>
          <name>Port</name>
          <type>int</type>
       </attribute>
       <attribute access="read-write" getMethod="getBacklog" setMethod="setBacklog">
          <description>The bootstrap socket backlog count.</description>
          <name>Backlog</name>
          <type>int</type>
       </attribute>
       <attribute access="read-write" getMethod="getJNPServerSocketFactory"
          setMethod="setJNPServerSocketFactory">
          <description>The bootstrap socket javax.net.ServerSocketFactory</description>
          <name>JNPServerSocketFactory</name>
          <type>java.lang.String</type>
       </attribute>
    
       <attribute access="read-write" getMethod="getRmiPort" setMethod="setRmiPort">
          <description>The port of the RMI naming service, 0 == anonymous. This
          is only used if an explicit InvokerProxyFactory has not been set.</description>
          <name>RmiPort</name>
          <type>int</type>
       </attribute>
       <attribute access="read-write" getMethod="getRmiBindAddress" setMethod="setRmiBindAddress">
          <description>The RMI service bind address. Empty == all addresses</description>
          <name>RmiBindAddress</name>
          <type>java.lang.String</type>
       </attribute>
       <attribute access="read-write" getMethod="getClientSocketFactory" setMethod="setClientSocketFactory">
          <description>The RMI service java.rmi.server.RMIClientSocketFactory</description>
          <name>ClientSocketFactory</name>
          <type>java.lang.String</type>
       </attribute>
       <attribute access="read-write" getMethod="getServerSocketFactory" setMethod="setServerSocketFactory">
          <description>The RMI service java.rmi.server.RMIServerSocketFactory</description>
          <name>ServerSocketFactory</name>
          <type>java.lang.String</type>
       </attribute>
    
       <attribute access="read-write" getMethod="getInstallGlobalService"
          setMethod="setInstallGlobalService">
          <name>InstallGlobalService</name>
          <type>boolean</type>
       </attribute>
       <attribute access="write-only" setMethod="setLookupPool">
          <description>The thread pool service used to control the bootstrap lookups</description>
          <name>LookupPool</name>
          <type>org.jboss.util.threadpool.BasicThreadPoolMBean</type>
       </attribute>
       <attribute access="write-only" setMethod="setInvokerProxyFactory">
          <description>The detached invoker proxy factory to use for the naming
          service transport.</description>
          <name>InvokerProxyFactory</name>
          <type>org.jboss.invocation.jrmp.server.JRMPProxyFactoryMBean</type>
       </attribute>
    
       <!-- Operations -->
       <operation>
          <description>The generic invocation operation used by detached invokers
             to route requests to the service
          </description>
          <name>invoke</name>
          <parameter>
             <description>The Naming interface method invocation encapsulation
             </description>
             <name>invocation</name>
             <type>org.jboss.invocation.Invocation</type>
          </parameter>
          <return-type>java.lang.Object</return-type>
       </operation>
    
       &defaultOperations;                  
    
    </mbean>
    

     

     

    The org.jboss.test.jmx.interceptors.JNDISecurity code is attached to the wiki.  The JNDISecurity.java.3.x works for JBoss 3.x.  JNDISecurity.java.4.x works for JBoss 4.0.x, 4.2.x and EAP 4.2/4.3.  The class should be compiled in a jar and put in $JBOSS_HOME/server/<Profile>/lib/ so that it will be availble when JBoss is started.

     

     

    Now you need to configure the NamingService to use the detached invoker framework to expose an org.jnp.interfaces.Naming interface proxy to JNDI clients in order to have the jndi lookups routed to the NamingService.invoke method. The following 3.2.6+ confg/jboss-service.xml fragement illustrates this for the RMI/JRMP detached invoker:

     

       <!-- The JRMP invoker proxy configuration for the naming service -->
       <mbean code="org.jboss.invocation.jrmp.server.JRMPProxyFactory"
          name="jboss:service=proxyFactory,type=jrmp,target=Naming">
          <!-- Use the standard JRMPInvoker from conf/jboss-service.xxml -->
          <attribute name="InvokerName">jboss:service=invoker,type=jrmp</attribute>
          <attribute name="TargetName">jboss:service=Naming</attribute>
          <attribute name="JndiName"></attribute>
          <attribute name="ExportedInterface">org.jnp.interfaces.Naming</attribute>
          <attribute name="ClientInterceptors">
              <interceptors>
                 <interceptor>org.jboss.proxy.ClientMethodInterceptor</interceptor>
                 <interceptor>org.jboss.proxy.SecurityInterceptor</interceptor>
                 <interceptor>org.jboss.invocation.InvokerInterceptor</interceptor>
              </interceptors>
          </attribute>
          <depends>jboss:service=invoker,type=jrmp</depends>
       </mbean>
    
       <mbean code="org.jboss.naming.NamingService"
          name="jboss:service=Naming"
          xmbean-dd="resource:xmdesc/NamingService-xmbean.xml">
          <!-- The call by value mode. true if all lookups are unmarshalled using
          the caller's TCL, false if in VM lookups return the value by reference.
          -->
          <attribute name="CallByValue">false</attribute>
          <!-- The listening port for the bootstrap JNP service. Set this to -1
            to run the NamingService without the JNP invoker listening port.
          -->
          <attribute name="Port">1099</attribute>
          <!-- The bootstrap JNP server bind address. This also sets the default
          RMI service bind address. Empty == all addresses
           -->
          <attribute name="BindAddress">${jboss.bind.address}</attribute>
          <!-- The thread pool service used to control the bootstrap lookups -->
          <depends optional-attribute-name="LookupPool"
             proxy-type="attribute">jboss.system:service=ThreadPool</depends>
          <!-- The detached pooled invoker proxy -->
          <depends optional-attribute-name="InvokerProxyFactory"
             proxy-type="attribute">jboss:service=proxyFactory,type=jrmp,target=Naming</depends>
       </mbean>
    
    

     

    Lastly, you need to define the JAAS login module configuration for the java:/jaas/secure-jndi security domain. See the JAAS Howto for examples of this.  Such as: LdapLoginModule ,DatabaseServerLoginModule,UsersRolesLoginModule