users@glassfish.java.net

AccessLocalException throws when security is activated

From: <glassfish_at_javadesktop.org>
Date: Tue, 03 Jul 2007 08:42:13 PDT

Hi everybody.

I have a trouble when calling a method of a stateless bean when security is activated on the glassfish server.
The following exception is thrown by the container :
[#|2007-07-03T17:19:26.622+0200|FINEST|sun-appserver9.1|javax.enterprise.system.core.security|_ThreadID=16;_ThreadName=p: thread-pool-1; w: 3;ClassName=com.sun.enterprise.security.provider.PolicyWrapper;MethodName=doImplies;_RequestID=a2095d43-c3df-4992-9cbf-81e77229ff18;|JACC Policy Provider: PolicyWrapper.implies, context (TestSecurity/TestSecurity)- result was(false) permission ((javax.security.jacc.EJBMethodPermission TestSecurityBean testSecurityCall,Remote,))|#]

[#|2007-07-03T17:19:26.622+0200|FINE|sun-appserver9.1|javax.enterprise.system.core.security|_ThreadID=16;_ThreadName=p: thread-pool-1; w: 3;ClassName=com.sun.enterprise.security.application.EJBSecurityManager;MethodName=authorize;_RequestID=a2095d43-c3df-4992-9cbf-81e77229ff18;|JACC: Access Control Decision Result: false EJBMethodPermission (Name) = TestSecurityBean (Action) = testSecurityCall,Remote, (Caller) = null|#]

[#|2007-07-03T17:19:26.622+0200|INFO|sun-appserver9.1|javax.enterprise.system.container.ejb|_ThreadID=16;_ThreadName=p: thread-pool-1; w: 3;TestSecurityBean;|EJB5018: An exception was thrown during an ejb invocation on [TestSecurityBean]|#]

[#|2007-07-03T17:19:26.622+0200|INFO|sun-appserver9.1|javax.enterprise.system.container.ejb|_ThreadID=16;_ThreadName=p: thread-pool-1; w: 3;|
javax.ejb.AccessLocalException: Client not authorized for this invocation.
        at com.sun.ejb.containers.BaseContainer.preInvoke(BaseContainer.java:1169)
        at com.sun.ejb.containers.EJBObjectInvocationHandler.invoke(EJBObjectInvocationHandler.java:189)
        at com.sun.ejb.containers.EJBObjectInvocationHandlerDelegate.invoke(EJBObjectInvocationHandlerDelegate.java:104)
        at $Proxy18.testSecurityCall(Unknown Source)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at com.sun.corba.ee.impl.presentation.rmi.ReflectiveTie._invoke(ReflectiveTie.java:125)
        at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.dispatchToServant(CorbaServerRequestDispatcherImpl.java:658)
        at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.dispatch(CorbaServerRequestDispatcherImpl.java:198)
        at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequestRequest(CorbaMessageMediatorImpl.java:1722)
        at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequest(CorbaMessageMediatorImpl.java:1582)
        at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleInput(CorbaMessageMediatorImpl.java:964)
        at com.sun.corba.ee.impl.protocol.giopmsgheaders.RequestMessage_1_2.callback(RequestMessage_1_2.java:179)
        at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequest(CorbaMessageMediatorImpl.java:734)
        at com.sun.corba.ee.impl.transport.SocketOrChannelConnectionImpl.dispatch(SocketOrChannelConnectionImpl.java:478)
        at com.sun.corba.ee.impl.transport.SocketOrChannelConnectionImpl.doWork(SocketOrChannelConnectionImpl.java:1360)
        at com.sun.corba.ee.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.run(ThreadPoolImpl.java:509)
|#]


In fact, i am trying the check the security activation of the application server. I activate it by the admin console and configure users for the file realm (declared as default realm).

I write a simple bean like this :

package test;


import javax.annotation.Resource;
import javax.annotation.security.DeclareRoles;
import javax.annotation.security.RolesAllowed;
import javax.ejb.Remote;
import javax.ejb.SessionContext;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.ejb.TransactionAttributeType;

import org.apache.log4j.Logger;


/**
 * @author fmosse
 *
 */
//Container Managed Transaction Demarcation :
@TransactionManagement(TransactionManagementType.CONTAINER)
@TransactionAttribute(TransactionAttributeType.REQUIRED)

@Stateless
@Remote( ITestSecurity.class)
@DeclareRoles( {"BeanRoleRef", "InvalidBeanRoleRef"})
public class TestSecurityBean implements ITestSecurity
{

        @Resource SessionContext ctx;
        
    // Logger
    private final Logger logger = Logger.getLogger (TestSecurityBean.class);

    @RolesAllowed("BeanRoleRef")
        public void testSecurityCall() {
                logger.debug("====================================TEST SECURITY CALL ====================");
                logger.debug("===========================================================================");
                logger.debug("==== Principal = " + ctx.getCallerPrincipal().getName());
                logger.debug("==== In Role'BeanRoleRef' = " + ctx.isCallerInRole("BeanRoleRef"));
                logger.debug("===========================================================================");
        }

    @RolesAllowed("InvalidBeanRoleRef")
        public void testInvalidRoleCall() {
                logger.debug("====================================TEST INVALID SECURITY CALL ====================");
                logger.debug("===========================================================================");
                logger.debug("==== Principal = " + ctx.getCallerPrincipal().getName());
                logger.debug("==== In Role'InvalidBeanRoleRef' = " + ctx.isCallerInRole("InvalidBeanRoleRef"));
                logger.debug("===========================================================================");
        }
    
}

The interface is also quite simple :
package test;
public interface ITestSecurity {
 
        
        public void testSecurityCall();
        public void testInvalidRoleCall();
}

Il defines role and role ref in the ejb-jar.xml like this :
<?xml version="1.0" encoding="UTF-8" ?>
 
<ejb-jar xmlns="http://java.sun.com/xml/ns/javaee"
                         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http:/java.sun.com/xml/ns/j2ee/ejb-jar_3_0.xsd"
                         version="3.0" >
        
        <display-name>TestSecurity-ejb</display-name>
                         
        <enterprise-beans>
                
                <session>
                        <ejb-name>TestSecurityBean</ejb-name>
                        <business-remote>test.ITestSecurity</business-remote>
                        <ejb-class>test.TestSecurityBean</ejb-class>
                        <session-type>Stateless</session-type>
                        <transaction-type>Container</transaction-type>
                        <security-role-ref>
                            <role-name>BeanRoleRef</role-name>
                            <role-link>BeanRole</role-link>
                        </security-role-ref>
                        <security-role-ref>
                            <role-name>InvalidBeanRoleRef</role-name>
                            <role-link>InvalidBeanRole</role-link>
                        </security-role-ref>
            </session>

        </enterprise-beans>

    <assembly-descriptor>
            <security-role>
                    <role-name>BeanRole</role-name>
            </security-role>
            <security-role>
                    <role-name>InvalidBeanRole</role-name>
            </security-role>
    </assembly-descriptor>
    
</ejb-jar>


And i make an association between users and supported roles in the sun-ejb-jar.xml like the here under :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sun-ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Application Server 9.0 EJB 3.0//EN" "http://www.sun.com/software/appserver/dtds/sun-ejb-jar_3_0-0.dtd">
<sun-ejb-jar>

  <security-role-mapping>
      <role-name>BeanRole</role-name>
      <principal-name>franck</principal-name>
  </security-role-mapping>

  <security-role-mapping>
      <role-name>InvalidBeanRole</role-name>
      <principal-name>lolo</principal-name>
      <principal-name>chack</principal-name>
  </security-role-mapping>

  <enterprise-beans>
    <unique-id>0</unique-id>
    <ejb>
      <ejb-name>TestSecurityBean</ejb-name>
      <jndi-name>TestSecurity</jndi-name>
      
      <pass-by-reference>false</pass-by-reference>
      <ior-security-config>
        <transport-config>
          <integrity>supported</integrity>
          <confidentiality>supported</confidentiality>
          <establish-trust-in-target>supported</establish-trust-in-target>
          <establish-trust-in-client>supported</establish-trust-in-client>
        </transport-config>
        <as-context>
          <auth-method>username_password</auth-method>
          <realm>default</realm>
          <required>true</required>
        </as-context>
        <sas-context>
          <caller-propagation>supported</caller-propagation>
        </sas-context>
      </ior-security-config>
      <is-read-only-bean>false</is-read-only-bean>
      <refresh-period-in-seconds>-1</refresh-period-in-seconds>
      <gen-classes/>
    </ejb>
        
  </enterprise-beans>
</sun-ejb-jar>



I create a stand alone client that connects to the bean using the programmatic login. The client code is like this :

/**
 *
 */
package test;

import java.util.Hashtable;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import com.sun.appserv.security.ProgrammaticLogin;


/**
 * @author fmosse
 *
 */
public class TestSecurityClient {

        /**
         * @param args
         * @throws Exception
         */
        public static void main(String[] args) throws Exception {
        try {
                Class.forName("com.sun.enterprise.naming.SerialInitContextFactory");
        }
        catch(ClassNotFoundException e) {
                System.exit(-1);
        }
                   
        // Test du lookup
        ITestSecurity testSecurity = null;


                try {
                testSecurity = (ITestSecurity)getCtx().lookup("test.ITestSecurity");
                } catch (NamingException e) {
                        e.printStackTrace();
                }


                testSecurity.testSecurityCall();

                testSecurity.testInvalidRoleCall();
                
        }

        public static InitialContext getCtx() throws Exception
        {
        // Definition des propriétés
        Hashtable<String, String> properties = new Hashtable<String, String> ();
        properties.put (Context.INITIAL_CONTEXT_FACTORY,"com.sun.enterprise.naming.SerialInitContextFactory");
            properties.put (Context.URL_PKG_PREFIXES,"com.sun.enterprise.naming");
            properties.put (Context.STATE_FACTORIES,"com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl");
        properties.put ("org.omg.CORBA.ORBInitialHost", "localhost");
        properties.put ("org.omg.CORBA.ORBInitialPort", "3700");

        // Récupération du context
                try {
                        System.setProperty("java.security.auth.login.config", "D:\\Sun\\SDK\\lib\\appclient\\appclientlogin.conf");
                        
                        ProgrammaticLogin pl = new ProgrammaticLogin();
                        InitialContext ic = new InitialContext( properties);
                       pl.login( "franck", "franck");
                        return ic;
                } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                        throw e;
                }
        }
        
}


The probleme is that i obtain a reference upon the remote bean, so the connection is successful but when i invoke the first method of the bean, the container throws the javax.ejb.AccessLocalException exception.

Can you help me to solvemy problem.

Thank you in advance for all your participation to this thread.

Regards
[Message sent by forum member 'franck_mosse' (franck_mosse)]

http://forums.java.net/jive/thread.jspa?messageID=225081