3 Replies Latest reply on Aug 8, 2006 2:04 AM by juergen.zimmermann

    Programmatically query @RolesAllowed or if caller can access

    matt10

      How do I find out programmatically which other methods can be called on a session bean by an authenticated user from in a bean method?

      From a client I'm trying to query what methods the user can call on the session bean, in order to enable and disable menu items and functionality as appropriate on the client.

      On the session bean I have created a method which is supposed to return a list of the methods accessible on the bean (simplified):

      @PermitAll
      public String[] getAllowedMethods() {
      ...
      }

      In this method I'm trying to iterate through the methods on the session bean checking to see if the caller has permission to access each one. I want to return a list of the accessible methods to the client. After a week of exploring, searching on forums and trying out code I cannot find a way to do this.

      I could find no methods which give me access to this metadata from the bean so I've tried querying the annotations myself from a static class reference to the actual Session Bean (MySessionBean.class) but the annotations come back as proxies and code reports there are no @Remote, @RolesAllowed etc. annotations on the class I have a reference to, so I presume the ClassLoader is returning me a bean proxy.

      I've looked at SessionContext, EJBHome, EJBMetaData seeking this security information about EJB methods but to no avail. All I have is a suspicion that the information I am looking for is available to interceptors.

      Anyone know how to query bean methods for roles allowed at runtime?

        • 1. Re: Programmatically query @RolesAllowed or if caller can ac
          wolfc

          This works for me:

          package test;
          
          import java.lang.annotation.Annotation;
          import java.lang.reflect.Method;
          
          import javax.annotation.security.RolesAllowed;
          import javax.ejb.Remote;
          import javax.ejb.Stateless;
          
          @Stateless
          @Remote(MyStateless.class)
          public class MyStatelessBean implements MyStateless {
          
           @RolesAllowed("user")
           public String sayHelloTo(String name) {
          // Annotation as[] = MyStatelessBean.class.getAnnotations();
          // for(Annotation a : as) {
          // System.err.println(a.toString());
          // }
           Method ms[] = getClass().getMethods();
           for(Method m : ms) {
           Annotation as[] = m.getAnnotations();
           for (Annotation a : as) {
           System.err.println(a.toString());
           }
           RolesAllowed rolesAllowed = m.getAnnotation(RolesAllowed.class);
           if(rolesAllowed != null) {
           for(String role : rolesAllowed.value()) {
           if(role.equals("user"))
           System.err.println("method " + m + " is allowed for user");
           }
           }
           }
           return "Hi " + name;
           }
          
           @RolesAllowed("admin")
           public void notAllowed()
           {
          
           }
          
           @RolesAllowed("user")
           public void allowed()
           {
          
           }
          }
          


          • 2. Re: Programmatically query @RolesAllowed or if caller can ac
            matt10

            Your code does work as expected. Thanks for your help.

            I was doing annotation.getClass() instead of annotation.annotationType() on the server-side coupled with a bug on client-side which was not handling the results properly. I had mislead myself that I could not access annotations after seeing Proxy$69 and similar as the class name instead of the annotations I wanted.

            • 3. Re: Programmatically query @RolesAllowed or if caller can ac
              juergen.zimmermann

              You also can do it this way

              // Get the authentified subject
              Subject subject = null;
              try {
               subject = (Subject) PolicyContext.getContext("javax.security.auth.Subject.container");
              }
              catch (PolicyContextException e) {
               LOG.error(...);
              }
              if (DEBUG) LOG.debug("Subject: " + subject);
              
              // Get all roles of the authentified subject
              // JBoss proprietary: via SimpleGroup
              final Set<Principal> principals = subject.getPrincipals(Principal.class);
              for (Principal p: principals) {
               if (p instanceof SimpleGroup) {
               final SimpleGroup sg = (SimpleGroup) p;
               if ("Roles".equals(sg.getName())) {
               final Enumeration roles = sg.members();
               while (roles.hasMoreElements()) {
               final String r = roles.nextElement().toString();
               if (DEBUG) LOG.debug("..." + r);
               }
               }
               }
              }