I have a servlet that returns data to users from a mapping system. Most of the data are publicly accessible, so those requests need to work without any security or login challenge.
Depending on the items requested in the URI and querystring, I may need to authorize the user to see some of the data. Determining whether the request requires security uses criteria in the querystring and a bit of other logic, so I can't use security constraints in the web.xml. I set up a servlet filter that checks to see if the request requires any secure roles. I can also figure out if the user is logged in and has those roles.
I have most of the pieces I need. What baffles me is how to make a user log in to a servlet some of the time, but not other times.
I've tried 2 things and hit dead ends:
1) Send back a 401 response. The browser asks them to log in and sends their username and password back in the header. (This is an URL-based RESTlike data service, so I'm using the basic browser pop-up login.) This 401 challenge gets me their info, but doesn't seem to authenticate with the container (Tomcat). With the user/pass, I can query our user database for the authentication and authorization myself, but this seems really, really ugly. Is there a way to make the container to do the authentication on a 401?
2) Use a RequestDispatcher to forward the request to another servlet mapping that does have security set up in the web.xml. Unfortunately, this bypasses the web.xml with no login challenge. The idea is that if servlet code forwards someone to another resource, you knew what you were doing and meant to send them there. Is there a way to enforce the forwarding using the web.xml settings?
The last thing I was thinking about is if there is a way to extend the security constraint to determine whether the request requires authentication or not?
Does anyone have an idea of how to make a servlet public some of the time, but ask for a login when it needs it?
Bear Bibeault wrote:If the decision is based on information available on the request, sounds like the perfect use for a filter.
Thanks. This is the same track I was on. In my filter, I was able to determine if they needed a login challenge. I figured out how to send a 401 challenge, and it popped up a login box in the browser. The user's response was just sending the user/pass back in the headers, but wasn't authenticating against the servlet container (Tomcat). If I could figure out how to get this to authenticate with the servlet container, I'd be back on track.
Joined: Jun 06, 2009
David Newton wrote:Two options off the top of my head:
1) Just do the login manually
2) Two servlets (could be the same class), one allows the access, one doesn't
Thanks. I thought of this, but I'm trying to keep the clients from having to know whether they need a login or not. I was hoping to just have one URL that simplifies everything and authenticates them if need be.
David Newton wrote:They'll probably notice when they have to log in.
I would like to provide one URL that asks for a login when needed. When I said I don't want the users to have to know whether their request requires security, I was replying to the suggestion of providing separate secure and public URLs.
If I can solve this problem, then hopefully my users will know what to do with the login pop-up!