4 Replies Latest reply on Oct 14, 2004 8:35 AM by leathurman

    Accessing User Defined Principles in an EJB

    leathurman

      I am using JAAS and I would like to introduce a new principal called ‘organisation’ which is the organisation of the logged in user. My understanding was that I could implement my own login module to retrieve and store the organisation as a principal on the subject.

      However my problem is that I can only use getCallerPrincipal and isUserInRole in the EJB’s, neither of which look like they provide access to user defined principals. How do I get access to the organisation information?

      Is it only accessible when you do the JAAS login which returns the subject. The only solution I can see is that I pass this token into every EJB call which I don’t really want to do as a I like the seamless propagation.

      I would be interested to know how others have approached this problem.

      Regards
      Lea.

        • 1. Re: Accessing User Defined Principles in an EJB
          websel

          I'm currently in the same process :-)

          First you need to enable authentication for your beans before the become principal & role aware.

          This is done with Xdoclet by adding the 'securityDomain' to your xdoclet task:

           <jboss version="${jboss.version}"
           xmlencoding="UTF-8"
           typemapping="${type.mapping}"
           datasource="${datasource.name}"
           unauthenticatedPrincipal="${unauthenticated.principal}"
           securityDomain="${jboss-ejb.securitydomain}"
           createTable="${create.table}"
           removeTable="${remove.table}"
           destdir="${build.dir}/META-INF"
           validateXml="true"/>
          

          The variables you see are definded in your ant.properties file supose your security domain is spawnzone.
          This will generate a code line in your jboss.xml:
           <jboss>
           <security-domain>java:/jaas/spawnzone</security-domain>
           <unauthenticated-principal>nobody</unauthenticated-principal>
           .......
          

          Now you're bean's in this jar will be authentication aware.
          add an xdoclet tag below the @ej.bean tag in your EJB class.
          @ejb.security-identity.
          Every bean you add this tag will become authentication aware.

          /**
           * @ejb.bean name ="MyEjb"
           * display-name = "MyEjbSB"
           * view-type = "both"
           * jndi-name = "ejb/MyEjb"
           * local-jndi-name = "ejb/MyEjbLocal"
           *
           * @ejb.security-identity
           * use-caller-identity = "true"
           * description = "Use Caller identity"
           */
          public class MyEjbBean implements SessionBean { .... }
          


          Now add to every method on your bean which roles can run them (don't forget your ejbCreate )
          Where @ejb.permission unchecked = "true" means anybody can invoke
          and
          @ejb.permission role-name = "wizard, systemadmin"
          only alllowes the wizard and the systemadmin to evoke this method
          example:
          /**
           * @ejb.create-method
           * @ejb.permission unchecked = "true"
           */
           public void ejbCreate() throws CreateException {}
          
           * @ejb.interface-method view-type = "both"
           * @ejb.permission role-name = "wizard, systemadmin"
           */
           public Collection getAllMyParties(){
           ........
           }
          
          


          For accessing these EJB's from a servlet or a standalone client use the callback handler as described in the JAAS Howto

          // code snippet
          // Anybody know how to get these two within a form based auth?
          // please let me know how to do that.. that's where i got lost here...
          
           String username = "wessel";
           String password = "secret";
          
           LoginContext lc = null;
           try{
           AppCallbackHandler handler = new AppCallbackHandler(username, password.toCharArray() );
           lc = new LoginContext("spawnzone", handler);
           System.out.println("Created LoginContext");
           lc.login();
           System.out.println("Logged in.");
           Iterator it = lc.getSubject().getPrincipals().iterator();
           while(it.hasNext()) {
           Object o = it.next();
           System.out.println("principle: "+o.getClass().getName()+ " "+o);
           }
           }catch (LoginException le){
           System.out.println("Login failed");
           le.printStackTrace();
           }
          
          // Use this as a static inlined class.
          // Watch out the callbacks should have [ and ] with and i in ther ;-)
           static class AppCallbackHandler implements CallbackHandler {
           private String username;
           private char[] password;
          
           public AppCallbackHandler(String username, char[] password){
           this.username = username;
           this.password = password;
           }
          
           public void handle(Callback[] callbacks)
           throws java.io.IOException, UnsupportedCallbackException {
           for (int i = 0; i < callbacks.length; i++) {
           if (callbacks instanceof NameCallback){
           NameCallback nc = (NameCallback)callbacks ;
           nc.setName(username);
           } else if (callbacks instanceof PasswordCallback) {
           PasswordCallback pc = (PasswordCallback)callbacks ;
           pc.setPassword(password);
           } else {
           throw new UnsupportedCallbackException(callbacks , "Unrecognized Callback");
           }
           }
           }
           }
          


          This will do the trick...
          If you know a way to have this work under a form based authenticated servlet , that would be way cool :-)

          Any comments or simplification please post, i'm still in the middle of this JAAS jungle :-)


          Wessel


          • 2. 3851412
            leathurman

            Hi Wessel,

            Thanks for taking the time to reply.

            I have JAAS working with the details being propagated through from the web layer to the EJB layer (using Form authentication and Filters) and everything secured and it all works fine.

            My question was really how you get access to user defined principal information inside the EJB. I can call getUserPrincipal which works fine, however I would like my beans to know more about the caller, specifically the organisation the user belongs to.

            I too am fighting my way through this but everything is starting to clear up. We have now come to the firm conclusion that J2EE declarative security is not flexible enough for our requirements (most notably the design time role/resource mapping). However we definately like the gains offered by JAAS.

            As a result we are writing our own login module. As we are not using web based authentication (or web based J2EE delarative security) we are propagating the info into the EJB using filters (as per Scots HowTo Doc). However I cannot see how I can get access to my "organisation principal"

            Do you use your own login module with additional principals?

            Regards
            Lea.

            • 3. Re: Accessing User Defined Principles in an EJB
              websel

              No just the default school-book example of a formbased authentication.
              As I work with struts I blocked all *.do requests untill there is a auth.
              The first action is the LogonAction, it is here i'm trying to fix the propagation of the authentication... I'm still a bit amazed that this seems such a problem..

              Wessel

              <security-constraint>
              - <web-resource-collection>
               <web-resource-name>Artomilito_Login</web-resource-name>
               <description>Main authentication for all the *.do's of the action servlet</description>
               <url-pattern>*.do</url-pattern>
               <http-method>GET</http-method>
               <http-method>POST</http-method>
               </web-resource-collection>
              - <auth-constraint>
               <role-name>serveradmin</role-name>
               <role-name>systemadmin</role-name>
               <role-name>wizard</role-name>
               </auth-constraint>
               </security-constraint>
              - <login-config>
               <auth-method>FORM</auth-method>
               <realm-name>Secured Area</realm-name>
              - <form-login-config>
               <form-login-page>/logon.jsp</form-login-page>
               <form-error-page>/logon.jsp</form-error-page>
               </form-login-config>
               </login-config>
              ........
              


              • 4. Re: Accessing User Defined Principles in an EJB
                leathurman

                Hi Wessel,

                Well we currently use out of the box form based authentication with J2EE declatative security and elsewhere we use filter based security. With both the propagation of the data through to the EJB works as you would expect and as per the excellent JAASHowTo documentation.

                Are you having a problem with this? If so whats the error you are getting as I maybe be able to help.