在servlet过滤器中保存并重用请求?

jri*_*her 7 java openid servlets servlet-filters

我正在编写一个基于JOID库的OpenID过滤器,以允许应用程序透明地对我们的本地OpenID服务器进行身份验证.由于OpenID通过HTTP重定向工作,我最终会丢失原始请求对象,特别是如果它是一个带有数据主体的POST.在用户通过身份验证后,是否可以以稍后在事务中重用它的方式保存请求对象?即使只是保存消息体本身就足够了,因为我可以通过往返重定向(通过使用OpenID的返回url)轻松保存查询URL.

我希望这对底层servlet完全透明,因此无论用户是通过此特定请求的OpenID流还是只有一个有效/经过身份验证的本地会话,它们的行为都相同.

Bal*_*usC 7

将感兴趣的数据(请求参数,请求属性等)存储在Map会话范围内,作为您添加到return-to-url的键的唯一ID.

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");
// ...
Run Code Online (Sandbox Code Playgroud)

然后当它返回时,用于HttpServletRequestWrapper包装当前请求,其中您覆盖getParameter()和consorts以返回感兴趣的原始数据.这样做是为了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);
Run Code Online (Sandbox Code Playgroud)

HttpServletRequestWithDataOfInterest可以是这样的:

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.
}
Run Code Online (Sandbox Code Playgroud)

注意:任何明显的nullcheck处理等都取决于您.