GeeCON Prague 2014*
The moose likes Servlets and the fly likes LDAP authentication + filter + redirect = mess Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


JavaRanch » Java Forums » Java » Servlets
Bookmark "LDAP authentication + filter + redirect = mess" Watch "LDAP authentication + filter + redirect = mess" New topic
Author

LDAP authentication + filter + redirect = mess

Irean Garland
Greenhorn

Joined: Aug 07, 2008
Posts: 5
Hello, I just stumbled upon the ranch and I am glad I did.

Well the reason I was searching the internets like mad for a few hours is this:

I need to integrate an old application into my employers standard LDAP authentication, using Struts, running on Websphere, replacing the old custom application-database login mechanism.

The way login was achieved was by having the login form action pointing to a Struts action which would then do the DB work and grant (or deny) access thru session variables.

Now, since LDAP login form must be called exactly 'j_security_check' for WAS to intercept it for LDAP authentication, keeping the Struts login action was out of the question (since actions must start with '/').

We decided the simplest way would be to retool the LoginAction class into a Servlet Filter, triggered by the 'j_security_check' URL. Sounded too easy to be true I know.

First thing I found out is, in order for the LDAP validation to go on, chain.doFilter(req, resp) must be called.

Second: The LDAP validation will print a message to the console, if the LDAP validation fails and that's it, no way to know it from the code. Well I was toying with the idea of hijacking the output stream to catch the 'LDAP authentication failed' message but that's just wrong and a huge security hole...

Third: Even if LDAP validation fails, it means nothing to doFilter, it will return to the next line.

At this point I thought it would simply be ugly but functional to ignore the LDAP authentication results and simply redirect to whatever page it was requested. If LDAP was ok it would show it, if not it would simply deny it and redirect back to the login page.

Wrong.

Turns out doing a doFilter call commits the response, making redirecting afterwards impossible.


So I guess that's it, after spending most of the afternoon reading on it I think I understand the problem and why it won't let me redirect, and I come asking you guys for even a hint of a work around this issue that can help me avoid meetings, paperwork and losing face.



Thanks in advance for reading/helping.
Irean Garland
Greenhorn

Joined: Aug 07, 2008
Posts: 5
I am pretty sure I gave my name when I signed up, not sure what happened but should be OK now.

Irean Garland
Greenhorn

Joined: Aug 07, 2008
Posts: 5
Well after a good night of sleep I figured out how to do this and it was crazy simple:


-Changed the Websphere welcome page to home.jsp, which is the page that should show upon a successful login both from LDAP and the app access database.
-Changed the filter (triggered when submitting the login form) to only handle the app DB access checks and set session variables acordingly, no redirect duties.

This works thanks to the fact that Websphere will re-redirect to the requested URL by itself after a successful login, if no specific URL is requested it will redirect to the welcome page after a successful login.

So this solved the only thing I couldn't do: redirect when LDAP login was successful. And since all the pages in the app have a session variable based access check routine at the start, I didn't have to change anything at all.



Deepak Bala
Bartender

Joined: Feb 24, 2006
Posts: 6661
    
    5

Changed the filter (triggered when submitting the login form) to only handle the app DB access checks and set session variables acordingly, no redirect duties.


I saw this a little too late. However i would like to understand what you have done.

I have to work with a similar scenario. We have a LDAP directory to authenticate against. The app server is weblogic. Weblogic automatically takes the LDAP users,groups and populates it into its set of users and groups. So to authenticate against LDAP it would be sufficient to authenticate against weblogic (using weblogic specific API if you want programmatic security. This spans about 2-3 lines of code).

You could also use the netscape API to communicate with the LDAP server. I cant remember if there is a login method but you can sure check if a user exists under a specific tree.

JAAS is also another option. Your login module could be implemented to talk with the LDAP server and return true or false based on whether the user exists in LDAP or not.

'j_security_check' for WAS to intercept it for LDAP


Are you attempting to intercept j_security_check calls ? Better not do something like that

I am not able to taste the flavor of your solution in full (although i can taste hints of chocolate ). Can you elaborate what you did a little more.


SCJP 6 articles - SCJP 5/6 mock exams - More SCJP Mocks
Irean Garland
Greenhorn

Joined: Aug 07, 2008
Posts: 5
Hi, I will try to explain to my best.

The reason why I have to keep a DB for app access checks is that we don't use the Groups/Roles functionality of LDAP, no idea why but I had to adhere to the standards.

I didn't know there was this netscape API, I will check it out just in case. Same goes for JAAS. Honestly I have little experience on enterprise environments, I was hired on a "don't worry you'll get it on the go" basis.

Oh, I am not trying to mess with 'j_security_check' calls. What I meant is it has to be named 'j_security_check' for Websphere to see it and know it has to intercept it for LDAP authentication. I wonder if actually Websphere uses JAAS in the backstage, since I saw a few login context exceptions once, when a firewall was messing up the communication with LDAP.


Now, to explain what I did:


Previously this application was not using LDAP, it authenticated users based on a custom DB user/pass, roles were kept in the database too.

My job is to get it to authenticate users with LDAP, user records and role information are still kept in the app DB since we don't use the Groups/Roles functionality of LDAP.

This app is Struts based so I first tried to use a Struts action mapped to 'j_security_check', this failed since the form action must be named exactly 'j_security_check' and that won't do with actions.

So next try was a filter triggered by 'j_security_check' URL, this would do almost the same as the action class the app used previously, check the app DB to see if the userName was registered for the app, if so, grab it and populate session variables with general access and role information which every page in the application verifies when called.

So, when the user was not on the app database, I would simply redirect to the noAccess.jsp page and not even call the LDAP check, if the user was in the app DB but failed the LDAP authentication then Websphere would redirect him to the noAccess.jsp page.

The problem was, if he was in the app DB and also ok LDAP I would have to redirect him to home.jsp, but after calling doFilter to trigger the LDAP check I couldn't issue a redirect anymore.

So what I did was simply change the welcome page for the application to home.jsp, this way upon a successful LDAP authentication (only called if the user was in the app DB) the user would be redirected there.

It was so simple I wanted to for spending hours trying to fix it in code.

Hope this makes things clear.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: LDAP authentication + filter + redirect = mess