springSecurity之如何添加自定义过滤器

目录

  • springSecurity 添加自定义过滤器
    • 很简单,配置如下
    • 然后再来看看myFilter
  • springSecurity 自定义认证过滤器
    • 出现的问题
    • 解决方法

springSecurity 添加自定义过滤器 我们知道,springSecurity其实就是将过滤器和aop进行整合。其实我们也可以添加自己的过滤器。

很简单,配置如下


然后再来看看myFilter
public class MyFilter implements Filter{@Overridepublic void init(FilterConfig filterConfig) throws ServletException { } @Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("进来了我自定义的过滤器了"); filterChain.doFilter(servletRequest,servletResponse); } @Overridepublic void destroy() {System.out.println("自定义过滤器链销毁了"); }}

其实只要实现了javax.servlet.Filter就可以了,很low.

springSecurity 自定义认证过滤器 继承 Filter 基类 OncePerRequestFilter 保证每个请求转发执行一次
public class MyAuthenticationProcessingFilter extends OncePerRequestFilter {protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)throws ServletException, IOException {filterChain.doFilter(requestWrapper, response); }


出现的问题
【springSecurity之如何添加自定义过滤器】在 filter 中消费了 Request 中的 InputStream 导致后续的过滤器中无法调用 Request

解决方法
定义一个 HttpServletRequestWrapper 类,将输入流字节数据读取出来,以供使用,重新 getInputStream() 方法,将输入流字节数组重新封装成 ServletInputStream 输入流即可,注意字符编码
ServletRequestWrapper.java
public class ServletRequestWrapper extends HttpServletRequestWrapper {private byte[] body; private String requestParam; /*** Constructs a request object wrapping the given request.* @Description: 将 request 中的流信息读取出来供外部使用,将流缓存起来,传到下一个 filter 中* @param request The request to wrap* @throws IllegalArgumentException if the request is null*/public ServletRequestWrapper(HttpServletRequest request) {super(request); requestParam = HttpUtil.getBodyString(request); body = requestParam.getBytes(Charset.forName("utf-8")); }@Overridepublic BufferedReader getReader() throws IOException {return new BufferedReader(new InputStreamReader(getRequest().getInputStream(), Charset.forName("UTF-8"))); }@Overridepublic ServletInputStream getInputStream() throws IOException {return new CustomServletInputStream(); }private class CustomServletInputStream extends ServletInputStream {private ByteArrayInputStream inputStream = new ByteArrayInputStream(body); @Overridepublic boolean isFinished() {return false; }@Overridepublic boolean isReady() {return false; }@Overridepublic void setReadListener(ReadListener listener) {}@Overridepublic int read() throws IOException {return inputStream.read(); }}public String getRequestParam() {return requestParam; }}

HttpUtil.java
public class HttpUtil {public static String getBodyString(ServletRequest request) {BufferedReader bufferedReader = null; InputStream inputStream = null; StringBuilder sb = new StringBuilder(""); try {inputStream = request.getInputStream(); bufferedReader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("utf-8"))); String line = ""; while ((line = bufferedReader.readLine()) != null) {sb.append(line); }} catch (IOException e) {e.printStackTrace(); } finally {if (bufferedReader != null) {try {bufferedReader.close(); } catch (IOException e) {e.printStackTrace(); }}if (inputStream != null) {try {inputStream.close(); } catch (IOException e) {e.printStackTrace(); }}}return sb.toString(); }}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

    推荐阅读