Showing posts with label maven. Show all posts
Showing posts with label maven. Show all posts

Tuesday, April 03, 2007

LDAP Logon and Password Management (part 2)

This is in continuation of my previous post. The PostLogonFilter Well today I am starting up with the filters. So I added the necessary entries to my web.xml file now. As I was writing it, I think I would be creating a separate java only project soon so I can keep the web app as customizable as possible. But for now all will be in the same project. So the PostLogonFilter would be mapped against /j_security_check and it will be invoked on a successful run of the validation. I was thinking of putting in a JUnit test to validate this, but I don't really know how to verify j_security_check on HttpUnit. Oh well, the app is very simple I think it would be way too overkill to automate the unit test on this one. Ugh, I feel dirty just saying that. Of course since you are going to be using servlet API, you really should include the javax.servlet servlet-api dependency. Grr, they should add that to the archetype as well. When I finish with this I am going to be writing a patch for that webapp archetype. Apparently I am using version 2.4 of the servlet API not the one I originally intended. I love maven, just one switch on the POM and poof we're on version 2.4 now. For now I put in a System.out in the filter, but I didn't see it on the console. I think it is because the jetty just eats it up. So I registered commons-logging and put in the message using commons logging. But that still didn't work. Found out the reason. j_security_check filters only work on WebSphere. Fortunately for me that is my target platform. Unfortunately I have no way of testing without deploying to that platform, I'd rather use Jetty because of speed. Anyway I used the Listener instead. Yes it is not ideal because it will get invoked for every request, but since the application is small and simple it shouldn't be too too bad.

public void requestDestroyed(final ServletRequestEvent sre) {
final HttpServletRequest httpServletRequest = (HttpServletRequest) sre
  .getServletRequest();
String mapping = httpServletRequest.getRequestURI().substring(
  httpServletRequest.getContextPath().length());
if ("/j_security_check".equals(mapping)
  && httpServletRequest.getUserPrincipal() != null) {
    System.err.println("yo " +
      httpServletRequest.getUserPrincipal().getName());
}
}
Is what I put in my code. Seems to work, getting the mapping is going to be a bit slow, but I'll work on optimizing it later. I will be changing the "yo" message with the expiration checks in a bit. However, all of the above does not work well. So how do I do it now? Well I made a Servlet that does the login instead, but forwards to j_security_check. The LogonServlet The logon servlet works suprisingly well. Of course it means that you have to use a non-standard servlet rather than j_security_check, but so what? Really it does not matter since this is a separate application and we can customize it as much as we want. So here is how it flows: Checking for expiration of passwords I took some concepts from a devWorks article on how to do this and for the most part it is fine, except that the netscape packages are not in an obvious place. However, I did find the Netscape LDAP SDK eventually and things just worked out for the best from that point. One gotcha that you have to note is when you reset the password, it will not expire in Tivoli, but rather it will return an error when you try to login. So rather than calling the method "check if password expired", I basically called it "checkPasswordChangeRequired" Further work Once I got the main flows all worked out, I just put struts around it to make the UI code more cleaner rather than having a lot of spaghetti JSP and servlets with embedded Java code. It also supports i18n when we have to port it to French. However, I am not going to cover that topic.

Monday, April 02, 2007

LDAP Logon and Password Management

I am just about to start off a new subproject which does logon and password management for LDAP. These are just my notes. Since this is for work, I can't post the full source code in the open, sorry. However, most of my readers should be competent enough to build it if they have to.

Some background

I don't like to create any unnecessary work for myself. Early on, I realized that when you log into one application in the application server, you are logged onto every application on the application server. This is with WebSphere and Tomcat. So I find it annoying when I go into a new project and I (or someone else) has to rebuild the logon use case with the change and manage password. Unfortunately, the proper enterprise solution tends to get expensive and is a separate project on its own. The proper enterprise solution would be an Identity Management solution such as Tivoli Identity Manager. Because of time constraints, I am going to do the YAGNI approach so everything would be in one uber project. I'll split it off later. My other goal is to make what I build into an archetype so we can use it with other projects as an asset.

Some notes to get me started

I have to hold the LDAP contexts so I do not use up any grace logins if I have to change the password on expiration. I do not intend to put in any detailed error messages aside from "you got an error". There is a servlet filter that after j_security_check it does the expiration checks and forwards to the right pages.

Starting things off

To start things off I am going to use Maven's webapp archetype:
mvn archetype:create -DarchetypeArtifactId=maven-archetype-webapp -DgroupId=org.xxx -DartifactId=XxxLogon

Getting into the IDE

And since I am an Eclipse user, I just typed the following in the directory mvn eclipse:eclipse I chose this approach over using the Eclipse plug-in, because I find that the maven command line plugin gets updated more regularly than that of the Eclipse plug-in. Unfortunately, the archtetype does not support WTP. This isn't much of a surprise for me since I had issues with Maven and WTP a year before. It is disappointing that these were not integrated with the archetype. Anyway I just added the plugin information and it seems to register as a webapp when I imported it into Eclipse. I then put in the maven jetty plug-in and test it out by going to http://localhost:8080/XxxLogon and "Hello world" comes out successfully. Nice I recommend this approach rather than using the servers that run on WTP, because (after experimenting) JSP changes get applied automatically, no need for a seperate publish step.

Security

Now I have to make it so it forces me to do a logon. However, when I put in the security-constraints (except for transport-guarantee which I know should not work because I didn't set up SSL) it gives me the error "No realm". It turns out I need to set up a realm, but I couldn't find any Realms for Jetty that uses LDAP so for now I used the HashUserRealm. I did this by adding the userRealms blob as shown in Maven2 Jetty Plugin: Configuration and created my realms.properties file that looks like trajano: passw0rd,everyone Once I did that I can log in properly.

SSO test

I decided to deploy to WebSphere Application Serer rather than Jetty since I haven't found out how to do multiple app deployments using the Jetty plugin. No biggie. I need to deploy it there in the end anyway. Ran the XxxLogon app entered my credentials then went to the URL of the real app. Works like a charm! Since I have eliminated the integration risk, I don't have to deal with that for a while now. Ya gotta like RUP's elaboration phase.

What's next?

In the next few days I am going to do the expiration handling and change of password.