4 Replies Latest reply on Nov 22, 2007 2:36 AM by kahliburke

    EntitySecurityListener and MDBs

    mtpettyp

      I've just recently started using Seam's JBoss Rules support for securing entities and I've run into an issue. When one of my MDBs tries to write to the database, I get the following exception:

      java.lang.IllegalStateException: No active session context
       at org.jboss.seam.security.Identity.instance(Identity.java:157)
       at org.jboss.seam.security.EntitySecurityListener.postLoad(EntitySecurityListener.java:26)
      ...
      


      This makes complete sense, as there obviously isn't a session context in an MDB.

      Anyone have any ideas on how to work around this? Ideally I'd like to be able to turn off EntitySecurityListener when running in my MDB, but I can't see an easy way to do this. Each method of EntitySecurityListener checks the static method Identity.isSecurityEnabled(), but if I was to turn security off it would affect my entire application, which is not desirable.

      I'd also like to be able turn off entity security for the duration of my authentication method (since I load the User entities to see if the passed-in credentials are valid, but would like to be able to protect access after logging in).

        • 1. Re: EntitySecurityListener and MDBs
          nhieb

          I was having the same problem, and used the nasty workaround-updating DB using querys:

          Query query=em.createQuery("update ..")
          query.executeUpdate();
          

          Hope somebody knows a better approach

          • 2. Re: EntitySecurityListener and MDBs
            mtpettyp

            I started hacking around with the source and I came up with the following solution:

            Change Identity.isSecurityEnabled():

             public static boolean isSecurityEnabled()
             {
             return securityEnabled &&
             Contexts.isSessionContextActive()&&
             Identity.instance().isIdentitySecurityEnabled();
             }
            


            Add the following methods to Identity:

             private boolean identitySecurityEnabled;
             <snip/>
            
             public boolean isIdentitySecurityEnabled()
             {
             return identitySecurityEnabled;
             }
            
             public void setIdentitySecurityEnabled(boolean enabled)
             {
             identitySecurityEnabled = enabled;
             }
            


            This solves both my problem mentioned above.

            If any of the Seam committers think this is a valid solution I can create a JIRA issue and attach the patch.


            • 3. Re: EntitySecurityListener and MDBs
              mtpettyp
              • 4. Re: EntitySecurityListener and MDBs
                kahliburke

                I would note that similar issues also affect methods called from asynchronous event handlers.

                I had 'read' rules on entities that caused them to be unavailable when loaded in an asynchronous method, because the rules still fire but there is no established session and nothing in the working memory to allow the permissions to be granted.

                I thought I could get around this issue by hooking into the 'org.jboss.seam.core.executingAsynchronousCall' variable that is set into the Event context when async methods are called. I added postSet and postRemove observers that would stick something into the working memory and had a rule that allowed all access in such cases. This would assume that any necessary permissions checks had already occurred before the async method was scheduled.

                However I then ran into my next issue:


                Caused by: java.lang.IllegalStateException: No active session context
                at org.jboss.seam.security.Identity.instance(Identity.java:157)
                at org.jboss.seam.security.EntitySecurityListener.preUpdate(EntitySecurityListener.java:44)



                It appears that the transaction is committed and the persistence context flushed outside of the methods that begin and end the call using the Lifecycle class. But the EntitySecurityListener is still active so we run into this issue.

                I'll workaround this problem for now by extending EntitySecurityListener to check whether an active session context exists, and whether the 'org.jboss.seam.core.executingAsynchronousCall' is in the event context.