users@glassfish.java.net

"Caller not authorized" calling a protected EJB method from a servlet

From: <glassfish_at_javadesktop.org>
Date: Fri, 13 Jul 2007 01:49:05 PDT

I'm getting the following stack trace while attempting to call a protected EJB method
from a servlet that has been marked with 'run-as'. I've search both these and the SUN
forums and have seem similar problems, but unfortunately, no resolutions.

The high-level process looks like this:
servlet (run-as 'registrant')
--> [EJB] RegistrantAuthenticator.authenticate(..)
     Has no role restrictions
--> [EJB] QuestionManager.getQuestionsForRegistrantWithAnswers(..)
     Has 'registrant_role' restriction

After the stack trace, I've put together a quick overview of the relevant pieces of the
application.

--8<-- stack trace from server.log
[#|2007-07-12T11:32:36.353+0100|FINE|sun-appserver-pe9.0|javax.enterprise.system.core.security|_ThreadID=18;_ThreadName=httpWorkerThread-8443-3;ClassName=com.sun.enterprise.security.application.EJBSecurityManager;MethodName=authorize;_RequestID=3a7683b3-1eaf-451f-8e49-5faa92dcc8db;|JACC: permission initialized in InvocationInfo: EJBMethodPermission (Name) = RegistrantAuthenticator (Action) = authenticateRegistrant,Remote,com.digitalsteps.jaas.AuthenticationData|#]
...
[#|2007-07-12T11:32:36.353+0100|FINE|sun-appserver-pe9.0|javax.enterprise.system.core.security|_ThreadID=18;_ThreadName=httpWorkerThread-8443-3;ClassName=com.sun.enterprise.security.application.EJBSecurityManager;MethodName=authorize;_RequestID=3a7683b3-1eaf-451f-8e49-5faa92dcc8db;|JACC: Access Control Decision Result: true EJBMethodPermission (Name) = RegistrantAuthenticator (Action) = authenticateRegistrant,Remote,com.digitalsteps.jaas.AuthenticationData (Caller) = null|#]

[#|2007-07-12T11:32:45.288+0100|FINE|sun-appserver-pe9.0|javax.enterprise.system.core.security|_ThreadID=18;_ThreadName=httpWorkerThread-8443-3;ClassName=com.sun.enterprise.security.application.EJBSecurityManager;MethodName=authorize;_RequestID=3a7683b3-1eaf-451f-8e49-5faa92dcc8db;|JACC: permission initialized in InvocationInfo: EJBMethodPermission (Name) = QuestionManager (Action) = getQuestionsForRegistrantWithAnswers,Local,java.lang.String|#]

[#|2007-07-12T11:32:45.308+0100|FINE|sun-appserver-pe9.0|javax.enterprise.system.core.security|_ThreadID=18;_ThreadName=httpWorkerThread-8443-3;ClassName=com.sun.enterprise.security.application.EJBSecurityManager;MethodName=getCachedProtectionDomain;_RequestID=3a7683b3-1eaf-451f-8e49-5faa92dcc8db;|JACC: new ProtectionDomain added to cache|#]

[#|2007-07-12T11:32:45.318+0100|FINE|sun-appserver-pe9.0|javax.enterprise.system.core.security|_ThreadID=18;_ThreadName=httpWorkerThread-8443-3;ClassName=com.sun.enterprise.security.application.EJBSecurityManager;MethodName=getCachedProtectionDomain;_RequestID=3a7683b3-1eaf-451f-8e49-5faa92dcc8db;|JACC: returning cached ProtectionDomain - CodeSource: ((file:/LISA-JAS/LISA-JAS-ejb_jar <no signer certificates>)) PrincipalSet: registrant|#]

[#|2007-07-12T11:32:45.358+0100|INFO|sun-appserver-pe9.0|javax.enterprise.system.core.security|_ThreadID=18;_ThreadName=httpWorkerThread-8443-3;|JACC Policy Provider: PolicyWrapper.implies, context(LISA-JAS/LISA-JAS-ejb_jar)- permission((javax.security.jacc.EJBMethodPermission QuestionManager getQuestionsForRegistrantWithAnswers,Local,java.lang.String)) domain that failed(ProtectionDomain (file:/LISA-JAS/LISA-JAS-ejb_jar <no signer certificates>)
 null
 (principals com.sun.enterprise.deployment.PrincipalImpl "registrant")

 java.security.Permissions_at_7dca91 (
  ...
 (javax.security.auth.PrivateCredentialPermission javax.resource.spi.security.PasswordCredential * "*" read)
 (java.io.FilePermission <<ALL FILES>> read,write)
 (java.net.SocketPermission localhost:1024- listen,resolve)
 (java.net.SocketPermission * connect,resolve)
)

)|#]

[#|2007-07-12T11:32:45.398+0100|FINE|sun-appserver-pe9.0|javax.enterprise.system.core.security|_ThreadID=18;_ThreadName=httpWorkerThread-8443-3;ClassName=com.sun.enterprise.security.application.EJBSecurityManager;MethodName=authorize;_RequestID=3a7683b3-1eaf-451f-8e49-5faa92dcc8db;|JACC: Access Control Decision Result: false EJBMethodPermission (Name) = QuestionManager (Action) = getQuestionsForRegistrantWithAnswers,Local,java.lang.String (Caller) = null|#]

[#|2007-07-12T11:32:45.408+0100|INFO|sun-appserver-pe9.0|javax.enterprise.system.container.ejb|_ThreadID=18;_ThreadName=httpWorkerThread-8443-3;QuestionManager;|EJB5018: An exception was thrown during an ejb invocation on [QuestionManager]|#]

[#|2007-07-12T11:32:45.408+0100|INFO|sun-appserver-pe9.0|javax.enterprise.system.container.ejb|_ThreadID=18;_ThreadName=httpWorkerThread-8443-3;|
javax.ejb.AccessLocalException: Client not authorized for this invocation.
        at com.sun.ejb.containers.BaseContainer.preInvoke(BaseContainer.java:1143)
        at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:182)
        at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:118)
        at $Proxy148.getQuestionsForRegistrantWithAnswers(Unknown Source)
...
--8<--

(A) EAR:
   sun-application.xml
   <sun-application>
      <security-role-mapping>
         <role-name>registrant_role</role-name>
         <group-name>registrant</group-name>
      </security-role-mapping>
      ...
      <realm>file</realm>
   </sun-application>

(B) EJB:
   @Stateless
   public class QuestionManagerBean implements IQuestionManagerLocal, IQuestionManagerRemote
   {
      ...
   }

   @Local
   @RolesAllowed({"registrant_role", "registration_officer_role", "registration_manager_role"})
   public interface IQuestionManagerLocal
   {
      ...
   }

   @Remote
   @RolesAllowed({"registrant_role", "registration_officer_role", "registration_manager_role"})
   public interface IQuestionManagerRemote
   {
      ...
   }


(C) WEB:
   public class ActivateAccount extends HttpServlet
   {
      ...
   }

   web.xml
   <web-app>
      <servlet>
         <servlet-name>ActivateAccount</servlet-name>
         <servlet-class>test.ActivateAccount</servlet-class>
         <run-as>
            <role-name>ejb_registrant_role</role-name>
         </run-as>
      </servlet>
      ...
      <security-role>
         <role-name>ejb_registrant_role</role-name>
      </security-role>
   </web-app>

   sun-web.xml
   <sun-web-app>
      <servlet>
         <servlet-name>ActivateAccount</servlet-name>
         <principal>registrant</principal>
      </servlet>
      ...
   </sun-web-app>

(D) Server configuration
- in Configuration > Security
   - default realm is 'file'
   - default principal is deliberately left blank
   - default role to group mapping is NOT active
- in Configuration > Security > Realms > file
   - user 'registant' with group(s) 'registrant' is present

(E) Generated granted.policy file:
grant principal com.sun.enterprise.deployment.Group "registrant" {
  permission javax.security.jacc.EJBMethodPermission "QuestionManager", ",Local";
  permission javax.security.jacc.EJBMethodPermission "QuestionManager", ",Remote";
  permission javax.security.jacc.EJBMethodPermission "QuestionManager", "createQuestion,Local,com.digitalsteps.lisa.questionmanager.SecurityQuestion,long";
  permission javax.security.jacc.EJBMethodPermission "QuestionManager", "createQuestion,Remote,com.digitalsteps.lisa.questionmanager.SecurityQuestion,long";
  permission javax.security.jacc.EJBMethodPermission "QuestionManager", "createQuestions,Local,java.util.List,java.lang.String";
  permission javax.security.jacc.EJBMethodPermission "QuestionManager", "createQuestions,Local,java.util.List,long";
  permission javax.security.jacc.EJBMethodPermission "QuestionManager", "createQuestions,Remote,java.util.List,java.lang.String";
  permission javax.security.jacc.EJBMethodPermission "QuestionManager", "createQuestions,Remote,java.util.List,long";
  permission javax.security.jacc.EJBMethodPermission "QuestionManager", "getAllSystemQuestions,Local,";
  permission javax.security.jacc.EJBMethodPermission "QuestionManager", "getAllSystemQuestions,Remote,";
  permission javax.security.jacc.EJBMethodPermission "QuestionManager", "getQuestionsForRegistrant,Local,java.lang.String";
  permission javax.security.jacc.EJBMethodPermission "QuestionManager", "getQuestionsForRegistrant,Local,long";
  permission javax.security.jacc.EJBMethodPermission "QuestionManager", "getQuestionsForRegistrant,Remote,java.lang.String";
  permission javax.security.jacc.EJBMethodPermission "QuestionManager", "getQuestionsForRegistrant,Remote,long";
  permission javax.security.jacc.EJBMethodPermission "QuestionManager", "getQuestionsForRegistrantWithAnswers,Local,java.lang.String";
  permission javax.security.jacc.EJBMethodPermission "QuestionManager", "getQuestionsForRegistrantWithAnswers,Local,long";
  permission javax.security.jacc.EJBMethodPermission "QuestionManager", "getQuestionsForRegistrantWithAnswers,Remote,java.lang.String";
  permission javax.security.jacc.EJBMethodPermission "QuestionManager", "getQuestionsForRegistrantWithAnswers,Remote,long";
  permission javax.security.jacc.EJBMethodPermission "QuestionManager", "setQuestions,Local,java.util.List,long";
  permission javax.security.jacc.EJBMethodPermission "QuestionManager", "setQuestions,Remote,java.util.List,long";
  permission javax.security.jacc.EJBMethodPermission "QuestionManager", "validateAnswers,Local,java.util.List,java.lang.String";
  permission javax.security.jacc.EJBMethodPermission "QuestionManager", "validateAnswers,Local,java.util.List,long";
  permission javax.security.jacc.EJBMethodPermission "QuestionManager", "validateAnswers,Remote,java.util.List,java.lang.String";
  permission javax.security.jacc.EJBMethodPermission "QuestionManager", "validateAnswers,Remote,java.util.List,long";
  ...
};

(F) Generated ejb-jar.xml:
<ejb-jar>
  ...
  <assembly-descriptor>
    <security-role>
      <role-name>registrant_role</role-name>
    </security-role>
    ...
    <method-permission>
      <role-name>registrant_role</role-name>
      <method>
        <ejb-name>QuestionManager</ejb-name>
        <method-intf>Local</method-intf>
        <method-name>*</method-name>
      </method>
      <method>
        <ejb-name>QuestionManager</ejb-name>
        <method-intf>Remote</method-intf>
        <method-name>*</method-name>
      </method>
    </method-permission>
    ...
</ejb-jar>

Environment:
JDK1.6.0_01
SJSAS 9.0_01(b02_p01)
Windows XP

Any idea on how to diagnose this further or any observations / corrections are very
welcome.

Thanks,
Marcus
[Message sent by forum member 'redentis' (redentis)]

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