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