Save and reuse request in servlet filter?

I am writing an OpenID filter based on the JOID library to allow applications to transparently authenticate with our local OpenID server. Since OpenID works through HTTP redirects, I end up losing the original request object in the process, especially if it's a POST with a data body. Is it possible to save the request object so that I can reuse it later in the transaction after the user has been authenticated? Even enough to save the message body should be enough, since I can save the request URL quite easily with redirection to both ends (using OpenID return-to-url).

I want to make this completely transparent to the underlying servlets, so they behave the same way, regardless of whether the user went through the OpenID stream for this particular request or just has a valid / authenticated local session.

+6
java servlets servlet-filters openid
source share
4 answers

Store the data of interest (query parameters, query attributes, etc.) in Map in the session area using a unique identifier as the key that you add to the return URL.

 String id = UUID.randomUUID().toString(); DataOfInterest data = new DataOfInterest(request); Map<String, DataOfInterest> map = (Map<String, DataOfInterest) session.getAttribute("dataOfInterest"); map.put(id, data); returnToUrl += "?token=" + URLEncoder.encode(id, "UTF-8"); // ... 

And then when it returns, use HttpServletRequestWrapper to wrap the current request, in which you override getParameter() and spouses to return the original data of interest. Do it in Filter .

 String id = request.getParameter(token); Map<String, DataOfInterest> map = (Map<String, DataOfInterest) session.getAttribute("dataOfInterest"); DataOfInterest data = map.remove(id); chain.doFilter(new HttpServletRequestWithDataOfInterest(request, data), response); 

HttpServletRequestWithDataOfInterest might look like this:

 public class HttpServletRequestWithDataOfInterest extends HttpServletRequestWrapper { private DataOfInterest data; public HttpServletRequestWithDataOfInterest(HttpServletRequest request, DataOfInterest data) { super(request); this.data = data; } public String getParameter(String name) { return data.getParameter(name); } public String[] getParameterValues(String name) { return data.getParameterValues(name); } // Etc, only when necessary. } 

Note: any obvious feedback from nullcheck, etc. it depends on you.

+6
source share

For general use, it will be more difficult than saving only the request body, you also need to save headers, etc.

You can check how it is implemented in Spring Security .

+2
source share

No, you cannot save the request. But you can create your own filter and add an object to the session area. Objects that have access to the session can use any found object.

+1
source share

What is it worth (and for anyone coming here in the future), after battling this for about a week, I ended up switching my application to using Spring Security completely instead of a standalone custom filter, and it works Great. Spring's security engine handles a lot of odd redirection and delayed request issues, which I started to write myself.

Thanks to everyone for their suggestions.

0
source share

All Articles