Skip to Content.
Sympa Menu

shibboleth-dev - [Shib-Dev] Creating a Custom LoginHandler for Novel's eDirectory to handle Grace Logins/Expired Passwords

Subject: Shibboleth Developers

List archive

[Shib-Dev] Creating a Custom LoginHandler for Novel's eDirectory to handle Grace Logins/Expired Passwords


Chronological Thread 
  • From: "Khanna, Sumit (khannast)" <>
  • To: "" <>
  • Subject: [Shib-Dev] Creating a Custom LoginHandler for Novel's eDirectory to handle Grace Logins/Expired Passwords
  • Date: Tue, 26 Apr 2011 15:57:57 -0400
  • Accept-language: en-US
  • Acceptlanguage: en-US

 

So I’ve done a lot of searching and coding trying to figure this out and so far I’m just very confused. I’ll explain what I have so far. Basically my school uses Novell eDirectory. Novell has some proprietary stuff for grace logins (you can bind to LDAP after your account expires for n times). A simple dirty way to indicate if an account is expired, locked, etc, would be to use the exception in the login.jsp like so:

 

 

                        <% if (request.getAttribute(LoginHandler.AUTHENTICATION_EXCEPTION_KEY) != null) {

                                String loginMsg = ((Exception)request.getAttribute(LoginHandler.AUTHENTICATION_EXCEPTION_KEY)).getMessage().trim();

                                String niceMsg = "";

 

                                if(loginMsg.contains("Cannot authenticate dn, invalid dn") || loginMsg.contains("669")) {

                                  niceMsg = "Invalid username or password";

                                }

                                else if(loginMsg.contains("222")) {

                                  niceMsg = "Password has expired";

                                }

                                else if(loginMsg.contains("220")) {

                                  niceMsg = "Account is disabled";

                                }

                                else if(loginMsg.contains("217")) {

                                  niceMsg = "Number of concurrent connections exceeded";

                                }

                                else if(loginMsg.contains("197")) {

                                  niceMsg = "Account is locked";

                                }

                                else if(loginMsg.contains("218")) {

                                  niceMsg = "Login time limited";

                                }

                                else {

                                  niceMsg = "An unknown authentication error occured";

                                }

                        %>

                          <span style="color:red; background-color:white; padding: 5px;"><%= niceMsg %></span>

                        <% } %>

 

 

However, our password change application binds as the user changing his or her password, so a grace login is used up on the password change itself. With the above example, the login would only fail after all the grace logins are gone too.

 

I’ve found several discussions which simply say “Write a custom Login Handler” but I haven’t found any good explanations on how to do that. I realize with LDAP we have Shibboleth setup to utilize the UsernamePasswordLoginHandler along with Virginia Tech’s LDAP/JAAS connector for authentication. I looked at the LoginHandler and Servlet first:

 

http://svn.middleware.georgetown.edu/view/java-idp/trunk/src/main/java/edu/internet2/middleware/shibboleth/idp/authn/provider/UsernamePasswordLoginHandler.java?view=markup

 

The Handler looks very basic. Even looking at the AbstractHandler, I don’t entirely understand how the username/password is passed to the JAAS provider, but it seems I was looking in the wrong place to do this type of expired password check anyway. I’d want to do it during the point where the bind actually occurs so I can read LDAP attributes and throw custom exceptions. So next I looked at the VT middleware JAAS provider:

 

http://code.google.com/p/vt-middleware/source/browse/vt-ldap/trunk/src/main/java/edu/vt/middleware/ldap/jaas/LdapLoginModule.java

 

This actually confused me even more, because I remember when I was originally setting up and configuring Shibboleth, that I had trouble with the login.config and it looked like, in the log file, that the items in the login.conf were actually calling get() and set() methods within the LdapLoginModule class (similar to how properties are set using Spring). However in the LdapLoginModule, I don’t see those getters or setters for things like host, base, bindDn, etc, nor do I see them in the base class.

 

I created a concept of what I want just using JNDI:

 

            Hashtable env = new Hashtable();

            env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");

            env.put(Context.PROVIDER_URL, "ldaps://devldap.example.edu:636");

 

            env.put(Context.SECURITY_AUTHENTICATION,"simple");

            String username = readLine("username",true);

            String userDn = "cn=" + username + ",ou=People,o=example";

            env.put(Context.SECURITY_PRINCIPAL,userDn); // specify the username

            env.put(Context.SECURITY_CREDENTIALS,readLine("password",false))

                       

            LdapContext ctx = new InitialLdapContext(env,null);

            List<SearchResult> result = performSearch(ctx,"ou=People,o=example","(cn="+username+")");

           

            for(SearchResult s : result) {

                  Attributes a = s.getAttributes();

                  String exp = a.get("passwordExpirationTime").get(0).toString();

                  String remainingGrace = a.get("loginGraceRemaining").get(0).toString();

 

                  Date date = new SimpleDateFormat("yyyyMMddHHmmss").parse(exp);

                  if(date.before(new Date())) {

                        System.out.print("Password expired. " + remainingGrace + " logins left.");

                  }

                 

                  System.out.println(exp);

                  System.out.println(date);

            }

 

…and it works in correctly identifying if the password has expired and the user is on grace logins. Our current login system forces users to change their password even if grace logins remain, so I was thinking of just adding an exception to the JAAS class that I could pull in the login.jsp, leaving the other classes alone. At first I considered extending edu.vt.middleware.ldap.jaas.LdapLoginModules, but fields like authRequest are private and inaccessible.

 

So I was thinking of just copying all the code and modifying the login() function to add the check I need in that first try block. It looks like I’ll have to use the VT LDAP libraries too over standard JNDI libraries.

 

So before I start doing this, is this a good way of going about solving this problem? Where are the docs and tutorials for the Custom Login Handlers I keep reading about in searches on this e-mail list? Why can’t I find any other guides to this? Surely we can’t be the only university that uses eDirectory and needs to deal with expired and locked accounts.

 

What is the best practice for dealing with this type of login?

 

 

Sumit Khanna

Application Analyist

EAI Team - University of Cincinnati

 




Archive powered by MHonArc 2.6.16.

Top of Page