java 如何在java过滤器中更改servlet请求主体?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34155480/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to change servlet request body in java filter?
提问by Neda Esmaeili
How can I change request body in java filter to protect from XSS
attack?
I build HttpServletRequestWrapper
and use getparameter
for change body but
get stream close exception.
如何更改 Java 过滤器中的请求正文以防止XSS
攻击?我构建HttpServletRequestWrapper
并getparameter
用于更改主体但获得流关闭异常。
回答by Neda Esmaeili
XSSFilter.java
XSSFilter.java
public class XSSFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
XSSRequestWrapper wrappedRequest = new XSSRequestWrapper(
(HttpServletRequest) request);
String body = IOUtils.toString(wrappedRequest.getReader());
if(!"".equals(body))
{
JSONObject oldJsonObject = new JSONObject(body);
JSONObject newJsonObject = new JSONObject();
for(String key : oldJsonObject.keySet())
{
newJsonObject.put(key, XSSUtils.stripXSS(oldJsonObject.get(key).toString()));
}
wrappedRequest.resetInputStream(newJsonObject.toString().getBytes());
}
chain.doFilter(wrappedRequest, response);
}
}
XSSRequestWrapper .java
XSSRequestWrapper .java
public class XSSRequestWrapper extends HttpServletRequestWrapper {
private byte[] rawData;
private HttpServletRequest request;
private ResettableServletInputStream servletStream;
public XSSRequestWrapper(HttpServletRequest request) {
super(request);
this.request = request;
this.servletStream = new ResettableServletInputStream();
}
public void resetInputStream(byte[] newRawData) {
servletStream.stream = new ByteArrayInputStream(newRawData);
}
@Override
public ServletInputStream getInputStream() throws IOException {
if (rawData == null) {
rawData = IOUtils.toByteArray(this.request.getReader());
servletStream.stream = new ByteArrayInputStream(rawData);
}
return servletStream;
}
@Override
public BufferedReader getReader() throws IOException {
if (rawData == null) {
rawData = IOUtils.toByteArray(this.request.getReader());
servletStream.stream = new ByteArrayInputStream(rawData);
}
return new BufferedReader(new InputStreamReader(servletStream));
}
private class ResettableServletInputStream extends ServletInputStream {
private InputStream stream;
@Override
public int read() throws IOException {
return stream.read();
}
}
}
XSSUtils .java
XSSUtils .java
public class XSSUtils {
private XSSUtils()
{
}
public static String stripXSS(String value) {
return value == null ? value : escapeHtml4(value);
}
}
回答by Suresh Kumar Ramasamy
Since I do not have enough reputation to add a comment, I am adding it as an answer. After 3 years, I found the accepted answer to save me hours. At the same time, I had to fix couple of things, and hence adding...
由于我没有足够的声誉来添加评论,因此我将其添加为答案。3 年后,我找到了可以节省时间的公认答案。与此同时,我不得不修复几件事情,因此添加......
(1) A bug (missing assignment to rawData)
(1) 一个错误(缺少对 rawData 的赋值)
public void resetInputStream(byte[] newRawData) {
rawData = newRawData;
servletStream.stream = new ByteArrayInputStream(newRawData);
}
(2) A change necessitated over time. Reference: https://stackoverflow.com/questions/29208456/httpservletrequestwrapper-example-implementation-for-setreadlistener-isfinish
(2) 随着时间的推移需要改变。参考:https: //stackoverflow.com/questions/29208456/httpservletrequestwrapper-example-implementation-for-setreadlistener-isfinish