1 2 Previous Next 25 Replies Latest reply: Feb 23, 2007 4:29 PM by Gyanendra Hyoju RSS

    Custom Login Module

    Casey Boyd Novice

      I am trying to create a custom login module that will replace the ModelLoginModule.

      What needs to be done within my class?

      Do I extend UsernamePasswordLoginModule?
      What methods do I need to over write?
      What needs to be returned?

      I got a custom class already built and tried to plug it into the portal using the login-config.xml but I get a "HTTP Status 403 - Access to the requested resource has been denied" page...

      JBoss : 4.0.3
      MySQL: 4.1
      Portal: 2.2

      thanks

        • 1. Re: Custom Login Module
          Viet Master

          what's your goal with replacing the model login module ?

          • 2. Re: Custom Login Module
            Casey Boyd Novice

            To use Active Directory instead of Database authentication...

            I can not change the AD schema....thats were the custom comes in...

            Is this possible?

            thanks

            • 3. Re: Custom Login Module
              Doug Schnelzer Newbie

              I have setup Active Directory authentication for a client using JBoss Portal. We used the LDAP Login Module that is packaged with the JBoss AS. There are directions in the LDAP Login Module source file for connecting to Active Directory. We replicated usernames from Active Directory to the JBoss Portal tables, which is required so that JBoss Portal can manage roles, permissions, and preferences. You can either set up replication from Active Directory to the JBoss Portal schema or you can extend the LDAP login module to automatically create a JBoss Portal user if they don?t already exist in the JBoss Portal schema.

              I wouldn?t recommend replacing the JBoss Portal Login Module. Instead you can stack the LDAP (configured for AD) login module in front of the JBoss Portal login module.

              • 4. Re: Custom Login Module
                Casey Boyd Novice

                I used org.jboss.security.auth.spi.LdapLoginModule as a example....

                Created my own class....changed login-config.xml to point to my new class...

                Connected to Active Directory, authenticated user, got the Portal Role from a attribute on the user. Everything works....

                But, after the user is authenticated in my class....I get a "HTTP Status 403 -Access to the requested resource has been denied" page when a user tries to log in...

                Now, if a understand what you are saying, after the user is authenticated in my class, I need to check to see if user is in database, then if not, create user in database....I am fine with that...

                What I really dont understand is how to tell the portal frame work that this user has been authenticated. How does org.jboss.portal.core.security.jaas.ModelLoginModule get the user authenticated in the portal frame work?

                Kinda new to all this....sorry....

                thanks

                • 5. Re: Custom Login Module
                  Doug Schnelzer Newbie

                  I can tell you what I think is happening, but Julian will have to chime in to verify.

                  Your authentication via AD (Active Directory) is handling authentication, but during the Portal Server invocation (see jboss-service.xml, portal stack) the user is retrieved from the database using their username (line 83 in org.jboss.portal.core.aspects.server.UserInterceptor ? src 2.2.0). Since you don?t have the user in the JBoss Portal schema, then this is failing and you are probably throwing an error ?Cannot fetch user=???? in the log. Adapting the User Login module to use LDAP seems like a decent size task.

                  My recommendation would be to use the UserModule in your LDAP login module to check if the user exists

                  if (module == null)
                   {
                   module = (UserModule)new InitialContext().lookup("java:portal/UserModule");
                   }
                  
                   // Lookup
                   User user = module.findUserByUserName(userName);


                  If not, then create the user

                  User createUser(String name, String password, String realEmail) throws IllegalArgumentException, ModuleException;


                  Then in your login config make sure you are stacking the JBoss Portal Login module after your LDAP login module. You should mark the LDAP login module with the flag=?requisite?. This will force the login to fail if the AD authentication fails.

                  This is generally the approach I had it working for another client.

                  Let me know how it goes.


                  • 6. Re: Custom Login Module
                    Viet Master

                    correct Doug

                    the best way would be to implement a create user option on ModelLoginModule based on username/password stacking defined by jaas.

                    • 7. Re: Custom Login Module
                      Casey Boyd Novice

                      Thanks guys....got it to work...here is what I did...

                      1) Wrote my own AD Login Module extending UsernamePasswordLoginModule
                      2) Overwrote getUserPassword (returns empty string), validatePassword (Authenticates user against LDAP, if user not in database...do not log user in....so...user must be created in database before loggin in), getRoleSets (This adds the user role that was found in LDAP AND YOU MUST HAVE A "AUTHENTICATED" ROLE AS WELL...this is what I missed previously)
                      3) User is authenticated....

                      Works great....


                      thanks

                      • 8. Re: Custom Login Module
                        darren hartford Expert

                        Based on the information provided above, and to save other people many hours of re-creating what other people have figured out, here is a no-warranty class to help people get started (forgive the length):

                        package org.jboss.portal.core.security.jaas;
                        
                        /* LGPL blah blah blah */
                        /* @author dhartford */
                        import java.util.HashSet;
                        import java.util.Map;
                        
                        import javax.naming.InitialContext;
                        import javax.naming.NamingException;
                        
                        import org.jboss.portal.core.model.NoSuchUserException;
                        import org.jboss.portal.core.model.User;
                        import org.jboss.portal.core.modules.RoleModule;
                        import org.jboss.portal.core.modules.UserModule;
                        
                        import javax.security.auth.Subject;
                        import javax.security.auth.callback.CallbackHandler;
                        import javax.transaction.TransactionManager;
                        import org.jboss.portal.common.transaction.Transactions;
                        
                        public class ExtModelLoginModule extends org.jboss.portal.core.security.jaas.ModelLoginModule {
                        
                         protected String roleModuleJNDIName;
                        
                         public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options)
                         {
                         super.initialize(subject, callbackHandler, sharedState, options);
                        
                         // roleModuleJNDIName = (String)options.get("roleModuleJNDIName");
                         roleModuleJNDIName = "java:/portal/RoleModule";
                         // Some info
                         log.trace("roleModuleJNDIName = " + roleModuleJNDIName);
                         }
                        
                         @Override
                         protected String getUsersPassword()
                         {
                         //not used
                         return "";
                         }
                        
                         private RoleModule roleModule;
                         protected RoleModule getRoleModule() throws NamingException
                         {
                         if (roleModule == null)
                         {
                         roleModule = (RoleModule)new InitialContext().lookup(roleModuleJNDIName);
                         }
                         return roleModule;
                         }
                        
                         @Override
                         protected boolean validatePassword(String arg0, String arg1) {
                         //boolean superpass = super.validatePassword(arg0, arg0);
                        
                         try
                         {
                         TransactionManager tm = (TransactionManager)new InitialContext().lookup("java:/TransactionManager");
                         Transactions.required(tm, new Transactions.Runnable()
                         {
                         public Object run() throws Exception
                         {
                         try
                         {
                         UserModule module = getUserModule();
                         User user = module.findUserByUserName(getUsername());
                         System.out.println("found user o.k.");
                         return "ok";
                         }
                         catch (NoSuchUserException e)
                         {
                         System.out.println("NoSuchUser exception, trying to create user");
                         //assume username is also e-mail address
                         User newuser = getUserModule().createUser(getUsername(),"NONE",getUsername());
                         System.out.println("trying to add auth role");
                         System.out.println(getRoleModule().findRoles());
                         newuser.getRoles().add(getRoleModule().findRoleByName("User"));
                         System.out.println("user set: " + newuser.getUserName() + ": " + newuser.getRoles());
                         return "ok";
                         }
                         }
                         });
                        
                         } catch (Exception e1) {
                         // TODO Auto-generated catch block
                         e1.printStackTrace();
                         }
                        
                         //force valid return for now
                         return true;
                         }
                        
                        }
                        


                        In your login-config.xml, replace ModelLoginModule with this class name (ExtModelLoginModule) and make sure you have your LDAP-login-module defined in front of it and have the 'useFirstPass' option enabled.

                        Note that this does NOT help with the requirement that the LDAP login have an 'AUTHENTICATED' user...probably need to have a re-look to see if that should be a valid requirement in the Portal. ( I still have a problem with this in my environment).

                        Hope this saves someone else a lot of hours of pain and feel free to modify for your needs (and contribute back if you feel like it), it took me a while to figure it out. I left the sysout's to help people just starting to use the class to understand what is going on. NOTE: This is a work-around until a better solution is in place for the Portal.

                        -D

                        • 9. Re: Custom Login Module
                          Viet Master

                          we will put it in cvs and create a wiki entry for this.

                          many thanks

                          • 10. Re: Custom Login Module
                            Scott Dawson Apprentice

                            Did D. Hartford's code get added in CVS (or the wiki)? I've looked but I don't see it.

                            Thanks,
                            Scott

                            • 11. Re: Custom Login Module
                              Viet Master

                              we are waiting from another novell person to give us a refactored version of user module and role module that we will put in cvs.

                              • 12. Re: Custom Login Module
                                rincewind23 Newbie

                                I'm just working on getting this into the CVS checkout I've got (currently I have it in a separate war) then I'll sent it to Julien for approval.

                                Cheers,
                                KEv.

                                • 13. Re: Custom Login Module
                                  Matt Zukowski Newbie

                                  Has this been incorporated into the portal code? If so, which version? 2.2 or 2.4? I notice the Wiki has been updated, but the instructions listed there don't seem to apply for 2.2...

                                  • 14. Re: Custom Login Module
                                    Daniel Wasser Newbie

                                    Do I really have to override the validatePassword method and duplicate all my users into the portal db?
                                    We are using an identity provider which is not able to
                                    provide all features needed by the usermodule.
                                    Is there a way to use only the jaas authentication without the usermodule?

                                    Thank's
                                    Daniel

                                    1 2 Previous Next