如何加密过滤器中的响应数据

时间:2014-11-25 10:43:28

标签: java servlets encryption filter

我在写入HttpServletResponse之前尝试加密响应数据,所以我实现了自定义响应包装器和输出streram以及过滤器类,

问题是我需要加密整个响应数据一次,但没有write(String content)方法,但ServletOutputStream类中有三种方法可用write(int b)write(byte[] b)和{{ 1}}当我运行应用程序时,只有一个方法被称为write(byte[] b, int off, int len)

那么是否有任何解决方法可以将整个响应数据作为字符串,我可以调用encrypt(responseData)?

我的课程如下:

write(int b)

public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {

        HttpServletRequest httpServletRequest = (HttpServletRequest)request;
        HttpServletResponse httpServletResponse = (HttpServletResponse)response;
        BufferedRequestWrapper bufferedReqest = new BufferedRequestWrapper(httpServletRequest);  
        BufferedServletResponseWrapper bufferedResponse = new BufferedServletResponseWrapper(httpServletResponse);

        // pass the wrappers on to the next entry
        chain.doFilter(bufferedReqest, bufferedResponse);
}

我的自定义输出流类看起来像:

public class BufferedServletResponseWrapper extends HttpServletResponseWrapper {

    private final Logger LOG = LoggerFactory.getLogger(getClass());

    private ServletOutputStream outputStream;
    private PrintWriter writer;
    private MyServletOutputStream copier;

    public BufferedServletResponseWrapper(HttpServletResponse response) throws IOException {        
        super(response);
    }

    @Override
    public ServletOutputStream getOutputStream() throws IOException {
        LOG.info("getOutputStream");
        if (writer != null) {
            throw new IllegalStateException("getWriter() has already been called on this response.");
        }

        if (outputStream == null) {
            outputStream = getResponse().getOutputStream();
            copier = new MyServletOutputStream(outputStream);
        }

        return copier;
    }

    @Override
    public PrintWriter getWriter() throws IOException {
        LOG.info("getWriter");
        if (outputStream != null) {
            throw new IllegalStateException("getOutputStream() has already been called on this response.");
        }

        if (writer == null) {
            copier = new MyServletOutputStream(getResponse().getOutputStream());
            writer = new PrintWriter(new OutputStreamWriter(copier, getResponse().getCharacterEncoding()), true);
        }

        return writer;
    }

    @Override
    public void flushBuffer() throws IOException {
        if (writer != null) {
            writer.flush();
        } else if (outputStream != null) {
            copier.flush();
        }
    }

    public byte[] getCopy() {
        if (copier != null) {
            return copier.getCopy();
        } else {
            return new byte[0];
        }
    }

}

2 个答案:

答案 0 :(得分:2)

String str = new String(bufferedResponse .getCopy());

这将为您提供outputStream中的数据字符串。我可以在你的代码中看到你正在写字节和复印机。此复印机也可以在以后修改。

String encStr=Encrypt(str); // your encryption logic.

ServletOutputStream out= response.getOutputStream();

out.write(encStr.getByte()); //adding your encrypted data to response 
out.flush();
out.close();

答案 1 :(得分:1)

我通过这种方式解决了这个问题:

  1. 在响应包装器类中创建了一个自定义的ByteArrayOutputStream和PrintWriter实例。
  2. 修改了getOutputStream()和getWriter()方法,以使用在步骤1中创建的自定义实例。
  3. 最后,在doFilter()语句之后的过滤器中,从自定义编写器和输出流中检索响应数据。并将加密数据写入原始回复。
  4. 这里是响应包装器的样子:

    public class BufferedServletResponseWrapper extends HttpServletResponseWrapper {
    
            private final Logger LOG = LoggerFactory.getLogger(getClass());
    
        private ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        private PrintWriter writer = new PrintWriter(outputStream);
    
        public BufferedServletResponseWrapper(HttpServletResponse response)
                throws IOException {
            super(response);
        }
    
        @Override
        public ServletOutputStream getOutputStream() throws IOException {
            LOG.info("getOutputStream");
    
            return new ServletOutputStream() {
                @Override
                public void write(int b) throws IOException {
                    LOG.info("write int");
    
                    outputStream.write(b);
                }
    
                @Override
                public void write(byte[] b) throws IOException {
                    LOG.info("write byte[]");
    
                    outputStream.write(b);
                }
            };
        }
    
        @Override
        public PrintWriter getWriter() throws IOException {
            LOG.info("getWriter");
            return writer;
        }
    
        @Override
        public void flushBuffer() throws IOException {
            if (writer != null) {
                writer.flush();
            } else if (outputStream != null) {
                outputStream.flush();
            }
        }
    
        public String getResponseData() {
            return outputStream.toString();
        }
    
    }
    

    和doFilter()看起来像:

    public void doFilter(ServletRequest request, ServletResponse response,
                FilterChain chain) throws IOException, ServletException {
    
            HttpServletRequest httpServletRequest = (HttpServletRequest) request;
            HttpServletResponse httpServletResponse = (HttpServletResponse) response;
            BufferedServletResponseWrapper bufferedResponse = new BufferedServletResponseWrapper(
                    httpServletResponse);
    
            // pass the wrappers on to the next entry
            chain.doFilter(httpServletRequest, bufferedResponse);
    
            String responseData = bufferedResponse.getResponseData();
            String encryptedResponseData = encrypt(responseData);
            OutputStream outputStream = httpServletResponse.getOutputStream();
            outputStream.write(encryptedResponseData.getBytes());
            outputStream.flush();
            outputStream.close();
        }