Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Save and re-use a request in a servlet filter?

I am writing an OpenID filter based on the JOID library to allow applications to transparently authenticate against our local OpenID Server. Since OpenID works via 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 in a way that I can reuse it later in the transaction, after the user has been authenticated? Even just saving the message body itself should suffice, as I can preserve the query URL easily enough with a roundtrip redirect (by using the OpenID's return-to-url).

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

like image 463
jricher Avatar asked Dec 27 '10 22:12

jricher


People also ask

How filter is used in pre and post processing of request?

A filter is an object that is invoked at the preprocessing and postprocessing of a request. It is mainly used to perform filtering tasks such as conversion, logging, compression, encryption and decryption, input validation etc. The servlet filter is pluggable, i.e. its entry is defined in the web.

Which of the following is true about servlet filter?

Q 17 - Which of the following is true about filters? A - Servlet Filters are Java classes that can be used to intercept requests from a client before they access a resource at back end.

How would you retrieve a parameter from the servlet request?

getParameter() method to get the value of a form parameter. getParameterValues() − Call this method if the parameter appears more than once and returns multiple values, for example checkbox. getParameterNames() − Call this method if you want a complete list of all parameters in the current request.

How does FilterChain doFilter work?

The doFilter method of the Filter is called by the container each time a request/response pair is passed through the chain due to a client request for a resource at the end of the chain. The FilterChain passed in to this method allows the Filter to pass on the request and response to the next entity in the chain.


2 Answers

Store the data of interest (request parameters, request attributes, etc) in a Map in session scope by an unique ID as key which you add to the return-to-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 comes back, use HttpServletRequestWrapper to wrap the current request wherein you override the getParameter() and consorts to return the original data of interest. Do this in a 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);

The HttpServletRequestWithDataOfInterest can 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 nullcheck handling etc is up to you.

like image 91
BalusC Avatar answered Sep 29 '22 14:09

BalusC


For general purpose usage it would be more complex than save just a request body, you also need to save headers and so on.

You may check how it's implemented in Spring Security.

like image 27
axtavt Avatar answered Sep 29 '22 15:09

axtavt