Hi ,
The root cause of this problem is in the logs :
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
See that the Caller Principal being logged is NULL above. Have you
tried using an Application Client to invoke your EJB and see if that
works. I will investigate more in the mean time.
Thanks.
glassfish_at_javadesktop.org wrote:
>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
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: users-unsubscribe_at_glassfish.dev.java.net
>For additional commands, e-mail: users-help_at_glassfish.dev.java.net
>
>
>