12 Replies Latest reply on Oct 27, 2006 11:40 PM by jaikiran

    Principal from Servlet to EJB not propagating?

    forumer

      I need to get a user from a Servlet Request parameter and propagate it to EJB layer. But it is not happening!

      Thanks in advance for your help.

      This is the excerpt from login-config.xml. Note that I am using ClientLoginModule:

       <application-policy name = "myPolicy">
       <authentication>
       <login-module code = "org.jboss.security.auth.spi.UsersRolesLoginModule"
       flag = "required" />
      
       <login-module code = "org.jboss.security.ClientLoginModule" flag = "required">
       <module-option name="password-stacking">useFirstPass</module-option>
       </login-module>
       </authentication>
      
       </application-policy>
      


      This is how use a loginContext. users.properties and roles.properties files in application archive are being read correctly.

      
       CallbackHandler handler = new MyHandler("paramFromRequest");
       LoginContext lc = null;
       try
       {
       lc = new LoginContext("myPolicy", handler);
       lc.login();
       Subject subject = lc.getSubject();
       Set<Principal> principals = subject.getPrincipals();
       for(Principal p: principals)
       {
       log.info("name="+p.getName());
       log.debug("name="+p.getName());
       // JBoss Specific
       if (p instanceof SimpleGroup)
       {
       SimpleGroup sg = (SimpleGroup) p;
       if ("Roles".equals(sg.getName()))
       {
       log.debug("role-name=" + sg.toString());
       }
       }
       }
      
       } catch (LoginException e)
       {
       log.info("authentication failed... But this is just a test; Ignore it");
       e.printStackTrace();
       }
      


      Here is the handler:

      
       class MyHandler implements CallbackHandler
       {
       String name = null;
       public MyHandler(String name){this.name=name;}
       public void handle(Callback[] callbacks) throws IOException,
       UnsupportedCallbackException
       {
       for (int i = 0; i < callbacks.length; i++)
       {
       if (callbacks instanceof NameCallback)
       {
       NameCallback nc = (NameCallback) callbacks;
       nc.setName(name);
       } else if (callbacks instanceof PasswordCallback)
       {
       PasswordCallback pc = (PasswordCallback) callbacks;
       pc.setPassword(new char[0]);
       } else
       {
       throw new UnsupportedCallbackException(callbacks,
       "Unrecognized Callback");
       }
       }
       }
       }
      


      Here is the EJB Method call that I am expecting to fail but succeeds! Calls on "ctx" are commented out because I get "No valid security context for the caller identity" otherwise.

       @RolesAllowed("xxx")
       public List<String> getAllUserGroups()
       {
      // Principal callerPrincipal = ctx.getCallerPrincipal();
      // if(null == callerPrincipal) log.debug("callerPrincipal is null!");
      // else log.debug(callerPrincipal.getName());
       return getAllGroupsAsStrings();
       }
      
      
      


        • 1. Re: Principal from Servlet to EJB not propagating?
          jaikiran

          Are you sure the login is happening properly? In your handler, i see that the Password is an empty char array. What are the contents of your users.properties and roles.properties? More importantly ,try and obtain the TRACE level logs of jboss security package as mentioned in Q4 at:

          http://wiki.jboss.org/wiki/Wiki.jsp?page=SecurityFAQ

          Those logs will help in identifying the issue.

          • 2. Re: Principal from Servlet to EJB not propagating?
            forumer

            Thanks for your reply.

            Empty password is intentional and is specified in users.properties as such as shown below. An exception is caused and login does fail if I specify a non-empty password in users.properties:

            fm_full=
            


            roles.properties is:
            fm_full=FullUser
            


            Here is an excerpt from trace/debug log output. As you can see login is happening. However, the servlet, after doing the login is dispatching to jsp and what is disturbing is "runAs: null". Could this be the problem and what can be done to resolve this?

            2006-10-26 06:23:23,804 TRACE [org.jboss.security.auth.spi.UsersRolesLoginModule] commit, loginOk=true
            2006-10-26 06:23:23,804 TRACE [org.jboss.security.auth.spi.UsersRolesLoginModule] Checking user: fm_full, roles string: FullUser
            2006-10-26 06:23:23,804 TRACE [org.jboss.security.auth.spi.UsersRolesLoginModule] Adding to Roles: FullUser
            2006-10-26 06:23:23,804 TRACE [org.jboss.security.ClientLoginModule] commit, subject=Subject:
             Principal: fm_full
             Principal: Roles(members:FullUser)
            
            2006-10-26 06:23:23,804 TRACE [org.jboss.security.SecurityAssociation] pushSubjectContext, subject=Subject:
             Principal: fm_full
             Principal: Roles(members:FullUser)
            , sc=org.jboss.security.SecurityAssociation$SubjectContext@2fb8d6{principal=fm_full,subject=17825859}
            .
            .
            .
            2006-10-26 06:23:23,914 DEBUG [org.apache.catalina.core.ApplicationDispatcher] servletPath=/FleetAdminViewGroups.jsp, pathInfo=null, queryString=null, name=null
            2006-10-26 06:23:23,914 DEBUG [org.apache.catalina.core.ApplicationDispatcher] Path Based Forward
            2006-10-26 06:23:23,914 TRACE [org.jboss.web.tomcat.security.RunAsListener] jsp, runAs: null
            2006-10-26 06:23:23,914 TRACE [org.jboss.web.tomcat.security.RunAsListener] jsp, runAs: null
            
            


            To reiterate, I am expecting the call to the EJB method to fail as I have specified a non-existing roles in @RolesAllowed.

            Thanks

            • 3. Re: Principal from Servlet to EJB not propagating?
              jaikiran

               

              To reiterate, I am expecting the call to the EJB method to fail as I have specified a non-existing roles in @RolesAllowed.


              I should have noted this in your first post itself. Overlooked it though.

              Have you specified a security domain for the EJB either through annotation at class level or through the jboss.xml file? If you haven't then the EJB is NOT considered a secure one and the @RolesAllowed will be ignored.

              • 4. Re: Principal from Servlet to EJB not propagating?
                forumer

                Thanks, Jaikiran! That was the problem.

                Now at what point can I check request.isUserInRole("FullUser") after successful login? I am trying this method right after successful login. But it is returning false? I need to do make some programmatic decisions based on whether user is "in Role".

                Thanks

                • 5. Re: Principal from Servlet to EJB not propagating?
                  jaikiran

                   

                  Now at what point can I check request.isUserInRole("FullUser") after successful login?


                  I guess, not until the next request is generated.

                  I am trying this method right after successful login. But it is returning false?


                  Try the following method after successful login:

                  request.getRemoteUser();


                  I believe this will return you null which means that the request object hasnt yet been populated with the logged in user information. So until the next request object is generated, you will not have the logged in user information.

                  BTW, why are you doing manual login? Any specific requirement? You could have gone for FORM based authentication which would have done the same - since i see your login module is not doing anything special.

                  • 6. Re: Principal from Servlet to EJB not propagating?
                    forumer

                    As you suspected, request.getRemoteUser() is returning null.

                    There is one slight difference that makes me not use BASIC or FORM login; I am plucking the username out of the request header which is passed on to this servlet from a SSO framework.

                    All requests come through this servlet. So, yes, user principle and Subject are being created at every request.

                    So, is there a way I can do a IsUserInRole type check in the jsp's that this servlet dispatches to?

                    On a related note, what enables for this user to be propagated successfully to EJB layer, even though it's not available to the authenticating Servlet itself?

                    Thanks for your help!

                    • 7. Re: Principal from Servlet to EJB not propagating?
                      jaikiran

                       

                      So, yes, user principle and Subject are being created at every request.

                      So, is there a way I can do a IsUserInRole type check in the jsp's that this servlet dispatches to?


                      I dont see a way, you will be able to do that. Even if the servlet dispatches to jsps, the request object will remain the same which means the request.isUserInRole method is going to return you false.

                      • 8. Re: Principal from Servlet to EJB not propagating?
                        forumer

                        Thanks.

                        At what point do the roles "get into" the container? After all the EJB container is seeing these roles properly, after the jsp's make calls on EJBs. This will help my understanding a bit.

                        • 9. Re: Principal from Servlet to EJB not propagating?
                          jaikiran

                          I guess this is what your usecase is:

                          1) There's a request coming into your servlet
                          2) Your servlet does a JAAS login
                          3) Servlet dispatches the control to JSP
                          4) User does some action on JSP and submits the JSP
                          5) On submitting the JSP(i.e. on some user action on the JSP), an EJB is called.

                          If i have got your usecase right, then here's what is happening:

                          - After you do a login in Step#2 the request object is not yet populated with the user information(since the request object was created even before you had logged in), so using methods like getRemoteUser and isUserInRole is of no use.
                          - After step#4, when the user submits the JSP, a new request is created and this time the user information is populated appropriately, since the user is still logged in as a result of Step#2.
                          - So now when the EJB gets called, the user information is propogated to those EJB and you will be able to use methods like isUserInRole successfully.

                          • 10. Re: Principal from Servlet to EJB not propagating?
                            forumer

                            I think you have it mostly right...

                            However, the JSP that servlet dispatches to has calls to EJB's even before the form, on JSP, is submitted. So EJB's are being called while JSP is being loaded and before the form on JSP is submitted. I put the same statement, request.getRemoteUser(), right before and after the call to EJB. I still get null. Yet EJB methods are responding to their role setting!

                            Does it make sense to you that Roles are being propagated to EJB layer while they are not in Web layer?

                            Thanks

                            • 11. Re: Principal from Servlet to EJB not propagating?
                              forumer

                              I am wondering if the ClientLoginModule is consulted before calls are made to EJB! However, the web-layer doesn't do this consulting as it relies only on the request object!

                              I am just guessing! What do you think?

                              Thanks

                              • 12. Re: Principal from Servlet to EJB not propagating?
                                jaikiran

                                 

                                I am wondering if the ClientLoginModule is consulted before calls are made to EJB!


                                I *guess* that's right. I saw your application policy. Just for the sake of confirming this, try changing it to:

                                <application-policy name = "myPolicy">
                                 <authentication>
                                 <login-module code = "org.jboss.security.auth.spi.UsersRolesLoginModule"
                                 flag = "required" />
                                
                                 </authentication>
                                
                                 </application-policy>


                                Note that i have removed the ClientLoginModule entry. Now, i believe you will not be able to see the roles even in the EJB. Note that as per Q3
                                at :
                                http://wiki.jboss.org/wiki/Wiki.jsp?page=SecurityFAQ

                                the original application policy that you have is absolutely correct and i am asking you to change it only for the sake of testing.
                                I will be able to give you a definite answer only after checking some docs and code(and that will not be before next week).