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.
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.
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With