8 Replies Latest reply on Mar 11, 2008 9:30 PM by sbiwal

    Problems in doing JAAS login using code

    prassana

      Hi all,


      We have our portal users using windows NT clients. We want to do auto login to portal users (skip the login page). we have used jcifs NTLM filter. We are able to authenticate users with this arrangement. However we were not able to authorize the users.

      So we wrote a filter that gets the username and makes a call to login function. we then set the user principal and subject to SecurityAssociation as shown below.


      UsernamePasswordHandler handler = new UsernamePasswordHandler(httpRequest.getRemoteUser(), httpRequest.getRemoteUser().toCharArray());

      LoginContext lgnctx;

      try {
      lgnctx = new LoginContext("portal", handler);
      lgnctx.login();
      System.out.println("Subject:" + lgnctx.getSubject().toString());

      SecurityAssociation.setSubject(lgnctx.getSubject());
      SecurityAssociation.setPrincipal(new UserPrincipal(httpRequest.getRemoteUser()));
      SecurityAssociation.setCredential(httpRequest.getRemoteUser().toCharArray());


      NOTE : we have user password same as user name in the database jbp_users table.


      But when some portlets make call to check for "admin" role as in following code
      req.isUserInRole(ADMIN_ROLE)
      it fails even if the user logged in has admin role. This happens in a few portlets such as role management portlet.

      We are not confident about the method we used to set the user subject and principal. Can any one suggest another method to set the user subject and principal?

      Appreciate if any one suggests other methods for authorization.

      my environment is as follws
      JBoss Portal Version : jboss 2.6.1
      Did you get Portal from CVS : yes
      JBoss AS Version : JBoss AS 4.0.5
      Database Vendor and Version : MS SQL server 2005
      JDBC Connector : jdbc:jtds:sqlserver
      OS Platform : Windows NT


      thanks

        • 1. Re: Problems in doing JAAS login using code
          prassana

          I overrided the isUserInRole function of org.jboss.portal.portlet.impl.spi.AbstractSecurityContext, like this to solve getting the user roles from the SecurityAssociation (whose subject i set in the filter) and instead from the request object.

           public boolean isUserInRole(String roleName)
           {
           if(SecurityAssociation.getSubject() != null
           && req.getAuthType().equals("NTLM"))
           {
           boolean inRole = false;
           Object[] principals = SecurityAssociation.getSubject().getPrincipals(SimpleGroup.class).toArray();
          
           SimpleGroup roleGroup = null;
           for(int i=0; i<principals.length; i++)
           {
           SimpleGroup temp = (SimpleGroup)principals[ i];
           if(temp.getName().equals("Roles"))
           roleGroup = temp;
           }
          
           if(roleGroup != null && roleGroup.isMember(new UserPrincipal(roleName)))
           inRole = true;
          
           return inRole;
           }
           else
           return req.isUserInRole(roleName);
           }
          


          I have commented out all the security constraints, and the security-role-ref from the servlet definitions in web.xml

          It worked all well. But is it the right way to go about ?

          • 2. Re: Problems in doing JAAS login using code
            tellarsrinivasprabhu

            Is the above approach correct ? If not can any one suggest any better way to ahead ?


            thanks,
            tellarsrinivasprabhu

            • 3. Re: Problems in doing JAAS login using code
              ebiere

              i am having exactly the same problem of associating the authenticated logincontext for the duration of the httpsession.

              i have successfully initialized a logincontext and login method call.

              but i am still prompted for my username and password each time i try to access a secure resource/page. i believe my authenticated logincontext is not associated with the httpsession.

              Any contributions !!

              • 4. Re: Problems in doing JAAS login using code
                creative777

                I have posted several times on this, if you do a search you can find the posts.

                But, no this will not work as stated.

                • 5. Re: Problems in doing JAAS login using code
                  tellarsrinivasprabhu

                  Hi,

                  The approach we followed to solve this problem is to write our own custom valve for tomcat. We have set the user principals in tomcat container request object.

                  this has solved our problem as of now.


                  • 6. Re: Problems in doing JAAS login using code
                    likon

                    tellarsrinivasprabhu,
                    Could you pls post here an example of code?

                    • 7. Re: Problems in doing JAAS login using code
                      tellarsrinivasprabhu

                      hi,

                      All we did was that we created a custom valve that extends org.apache.catalina.valves.ValveBase;

                      in the invoke method , we added the user principals to the request using following lines of code.

                      .
                      List roles = new ArrayList();
                      roles.add("Authenticated");
                      roles.add("User");
                      roles.add("Admin");
                      roles.add("CustomRole"); // add any roles that you want to add depending on context
                      
                      .
                      .
                      request.setUserPrincipal(new GenericPrincipal(request.getContext().getRealm(), username,password, roles));
                      .
                      .
                      .
                      getNext().invoke(request, response);
                      


                      you can also create new subjects and add to SecurityAssociation


                      Group roleGroup = new SimpleGroup("Roles");
                      
                      for (int i = 0; i < roles.size(); i++) {
                      String rname = (String) roles.get(i);
                      Principal p = new UserPrincipal(rname);
                      roleGroup.addMember(p);
                      }
                      
                      Subject subj = new Subject();
                      subj.getPrincipals().add(new UserPrincipal(username));
                      subj.getPrincipals().add(roleGroup);
                      SecurityAssociation.setSubject(subj);
                      


                      Once you are done with this, next we have to tell the application that it has to go through the custom valve that we created. This is done by creating a new file called context.xml having the following entry (specify your custom valve class name)

                      <Context>
                       <Valve className="sample.util.CustomValve" />
                      </Context>


                      place this file xml along with web.xml (in jboss-portal.sar\portal-server.war\WEB-INF)

                      create a jar of your custom valve class file and put it in any lib dir. we put it in server\default\lib.

                      then restart the server .


                      Hope this will help,
                      tellarsrinivasprabhu

                      • 8. Re: Problems in doing JAAS login using code
                        sbiwal

                        Hi

                        I am working on a similar problem. I want to login a special user automatically to the portal the first time a user access it (lets say "user" in the below code).

                        I created a custom tomcat valve using the code described below. However the user is not authorized to access his dashboard (or any other /auth pages). I know I am missing something but can't put my finger on it.

                        I am using the standard JAAS IdentityLoginModule. I see that the Principal returned by the JBossSecurityMgrRealm is always null (becuase the security context is null).

                        Please help me. I have been breaking my head over this for a long time. I have read documentations and other posts on the forum but nothing is working for me.

                        Thanks,
                        Swati


                        package org.jboss.web.tomcat.security;
                        
                        import ..
                        
                        /** A valve that provides information on the jaas login exception seen in the
                         SecurityAssociation exception data. The useExceptionAsMsg flag indicates if
                         the exception message should be set as the http response message. The
                         exceptionHeader attribute if set is the header name that should be populated
                         with the exception message.
                        
                         @author Scott.Stark@jboss.org
                         @version $Revision: 57206 $
                         */
                        public class BasicAuthValve
                         extends ValveBase
                        {
                         private static Logger log = Logger.getLogger(BasicAuthValve.class);
                         private static boolean trace = log.isTraceEnabled();
                        
                         /** Should the exception message be used as the request status message */
                         private boolean useExceptionAsMsg = false;
                         /** A flag indicating if the auth exception thread local should be cleared */
                         private boolean clearAuthException = true;
                         /** The name of the reply header to use to return the exception message */
                         private String exceptionHeader = null;
                        
                         public boolean isUseExceptionAsMsg()
                         {
                         return useExceptionAsMsg;
                         }
                         public void setUseExceptionAsMsg(boolean useExceptionAsMsg)
                         {
                         this.useExceptionAsMsg = useExceptionAsMsg;
                         }
                        
                         public String getExceptionHeader()
                         {
                         return exceptionHeader;
                         }
                         public void setExceptionHeader(String exceptionHeader)
                         {
                         this.exceptionHeader = exceptionHeader;
                         }
                        
                         public void invoke(Request request, Response response)
                         throws IOException, ServletException
                         {
                         // TODO Auto-generated method stub
                         List roles = new ArrayList();
                         roles.add("Authenticated");
                         roles.add("User");
                         roles.add("Admin");
                         roles.add("CustomRole");
                        
                         String password = "user";
                         String username = "user";
                        
                         Principal p = this.getContainer().getRealm().authenticate(username, (String)null);
                         request.setUserPrincipal(new GenericPrincipal(request.getContext().getRealm(), username, password, roles));
                        
                         this.getNext().invoke(request, response);
                        
                         }
                        
                        }