Link to home
Start Free TrialLog in
Avatar of OnixExp
OnixExp

asked on

j_security_check authentication: multiple login forms?

Using Tomcat & Form based login authentication for a webapp, I'm looking for a way to display a different login page depending on the URL / area a user is trying to access. Is this possible to do in a single webapp?

A simple example would be that I have a page saying "hello there, please enter login" for a user area (http://server/webapp/), and "welcome, admin, please login here" if the person is trying to access (http://server/webapp/adminonly).

I've thought of some things but no luck so far implementing them:

- Tomcat "automatically" goes to the URL the user was trying to access after authentication succeeds. If I could read this URL in the login page I could know what to display.

- web.xml seems to allow only one login-config element (which specifies the login-form URL), but I don't know if the realm thing could help.

- I can give parameters in the login-config to the login page, for example my login error page is now set to the login_page.jsp?error=true, but I can't put any run-time arguments there like ?role=user/admin.

I know I can make a second webapp and specify a different login page in its web.xml, but this is not as efficient. Ideas?
Avatar of rrz
rrz
Flag of United States of America image

I have little knowledge of Form based login authentication. But, I do know that the user's password is transmitted as plain text. So, if you are unable to satisfy your requirements with your present approach, then you could consider using Filters.  See  the interface javax.servlet.Filter.  If you want to try that idea, then we could help you here.      rrz
Avatar of OnixExp
OnixExp

ASKER

rrz,

Thanks for the suggestion. Tomcat has the option of forcing secure transport, i.e. using https, but for this application it's not even essential that we do that (90% of the users will be using one time logins).

Anyway, I'd like to stick to the orginal approach as much as possible (i.e. no fundamental recoding of the login mechanism) because the application is pretty much live and stuff. So I need to stick with tomcat controlling access based on the URL and j_username + j_password -> j_security_check mechanism. I read a suggestion somewhere from someone who thought about catching these parameters in a jsp they build, and "hand them to the j_security_check" whilst requesting a secured URL, but I have no idea how I would implement that, even considering Filters.

Let me know if you have any further suggestions.
Does the container call a Filter before or after the Form based login authentication ?
Anybody know ?
To OnixExp,
If no one posts the answer, then maybe you should write code to find out.  rrz
Avatar of OnixExp

ASKER

Wrote a filter that displays the request URL:

public void doFilter(ServletRequest sReq, ServletResponse sResp, FilterChain fChain) throws IOException, ServletException {
      if (sReq instanceof HttpServletRequest) {
            HttpServletRequest httpRequest = (HttpServletRequest) sReq;
            System.out.println(httpRequest.getRequestURL());
      }
      fChain.doFilter(sReq, sResp);
}

Unfortunately it displays the URL for the login page, not the page the user first requested.
>Unfortunately it displays the URL for the login page, not the page the user first requested
Maybe I led you astray.   So, your filter is reached after authentication ?  

If you don't want to go the filter only route, then how about using an intermediate page which is not protected. In the  intermediate page you can store the orginal url in a session variable and then forward to the protected page.  But I have not tried this myself.  rrz
Avatar of OnixExp

ASKER

>Maybe I led you astray.   So, your filter is reached after authentication ?  

No, Tomcat appears to intercept the original request URL and replaces it with the login page URL before it reaches the filter. It then passes this (login page) URL to the filter (as if that was requested in the first place), and after that the login page is sent.

Example:
user: browses to "http://server/webapp/admin/index"
tomcat replaces request URL with "http://server/webapp/login"
filter is activated with "http://server/webapp/login"
http://server/webapp/login page is activated
at this point we don't know that the user requested "http://server/webapp/admin/index", only Tomcat knows this and will go there after auth. succeeds.

I guess it makes sense that with container based authentication, the original webapp never knows about it. In this context I don't understand your suggestion. How could I have an "intermediate page" that automatically receives the original (secured area) url if Tomcat never passes it before the user is authenticated?
ASKER CERTIFIED SOLUTION
Avatar of rrz
rrz
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of OnixExp

ASKER

I know that authentication is done as long as it is a client redirect (and not an internal server forward, this will bypass security), so that's no problem.

Doesn't your suggestion however, force users to a single page to get in to the secured area? I had thought about a similar mechanism, having a separate (nonsecured) page for each area type and storing a flag in the session that the login page could later read. But that means that users can't bookmark any of the secured pages and go there directly, because that will bypass the setting of the flag.

I could do something like allow a redirection URL parameter like "http://server/webapp/admin/index?goto=/admin/private/pageX" but this still disables direct bookmarking and introduces a lot of extra programming" compared to the benefit.

Thanks for the help so far though.
The only solution I can think of is to use Filters only. But I realize  that is not what you want to use.
I am sorry that I was unable to come up with any good ideas.
You can request that this question be deleted if no one else can help.     rrz
Avatar of OnixExp

ASKER

Thanks rrz,

I'll leave the question open for a while longer to see if anyone else can figure something out. If not I'd rather slap a B on this one and have it go to the archives (if you don't mind) than lose our discussion which might be valuable for others thinking about it.
Ok
Avatar of OnixExp

ASKER

Abandoned? Not by me :P
:)
Simple solution:

At the start of your login and login-error pages, include the following:

    if (request.getAttribute("javax.servlet.forward.request_uri") == null) {
        response.sendRedirect("/index.jsp");
    }

where /index.jsp is equivalant to some acceptable page to forward users to if they have inadvertantly hit the back button to reach the login page.

To create a logout function, make a logout.jsp that contains the following:

        session.invalidate();
        response.sendRedirect("/index.jsp");

Avatar of OnixExp

ASKER

TomBruser,

The problem is that a single webapp is serving multiple classes of users; each class needs its own login page. Requirement is that Tomcat's form based authentication must be used. How does your solution make this possible?
Oops... the last part of my message didn't paste.  This was a solution to a similar problem from another posting but does apply here as well.  You will need what I submitted before, plus you should use the javax.servlet.forward.request_uri attribute that is in the request.getAttribute() to determine how to display the login.  Note that you will still be confined to a single login.jsp page... it is up to you to code that page so that based on what you find in your request attributes you display the proper login page.  The first bit of code I pasted is actually in order to prevent your users from ever seeing a j_security_check unavailable type error.  Drop me a line if you have further questions.
Avatar of OnixExp

ASKER

girionis: s'ok

TomBruser: Thanks, that's exactly the kind of info I was hoping to get! I can't revoke my points to rrz and assign them to you, so check out my new thread to get the points.
Sorry, I did not know about that attribute.    Thank you  TomBruser.
>I can't revoke my points to rrz
I think you can ask a moderator to do it.
Avatar of OnixExp

ASKER

rrz: That's okay, he's received the points now and you helped somewhat too so I have no problem with leaving it like this :)