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

 更新时间:2021年08月26日 11:13:21   作者:虎哥和你一起学编程  
这篇文章主要介绍了springSecurity之如何添加自定义过滤器的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

springSecurity 添加自定义过滤器

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

很简单,配置如下

<http use-expressions="false" entry-point-ref="loginEntryPoint">
  <intercept-url pattern="/user.jsp" access="ROLE_USER,ROLE_ADMIN"/>
  <intercept-url pattern="/admin.jsp" access="ROLE_ADMIN"/>
  <intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY"/>
  <form-login/>
  <custom-filter ref="myFilter" position="LAST"/>
 </http> 
 <beans:bean id="myFilter" class="com.ezhiyang.springSecurity.MyFilter"/>

然后再来看看myFilter

public class MyFilter implements Filter{
    @Override
    public void init(FilterConfig filterConfig) throws ServletException { 
    }
 
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("进来了我自定义的过滤器了");
        filterChain.doFilter(servletRequest,servletResponse);
    }
 
    @Override
    public 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);
  }

出现的问题

在 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"));
  }
  @Override
  public BufferedReader getReader() throws IOException {
    return new BufferedReader(new InputStreamReader(getRequest().getInputStream(), Charset.forName("UTF-8")));
  }
  @Override
  public ServletInputStream getInputStream() throws IOException {
    return new CustomServletInputStream();
  }
  private class CustomServletInputStream extends ServletInputStream {
    private ByteArrayInputStream inputStream = new ByteArrayInputStream(body);
    @Override
    public boolean isFinished() {
      return false;
    }
    @Override
    public boolean isReady() {
      return false;
    }
    @Override
    public void setReadListener(ReadListener listener) {
    }
    @Override
    public 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();
  }
}

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

相关文章

  • 基于自定义BufferedReader中的read和readLine方法

    基于自定义BufferedReader中的read和readLine方法

    下面小编就为大家分享一篇基于自定义BufferedReader中的read和readLine方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2017-12-12
  • WebSocket 中使用 @Autowired 注入对应为null的解决方案

    WebSocket 中使用 @Autowired 注入对应为null的解决方案

    SpringBoot集成WebSocket时,会遇到service对象为null的情况,原因是Spring默认为单例模式与WebSocket的多对象模式相冲突,当客户端与服务器端建立连接时,会创建新的WebSocket对象,本文给大家介绍WebSocket 中使用 @Autowired 注入对应为null的问题,感兴趣的朋友一起看看吧
    2024-10-10
  • Java实现读取TXT和CSV文件内容

    Java实现读取TXT和CSV文件内容

    这篇文章主要为大家详细介绍了如何利用Java语言实现读取TXT和CSV文件内容的功能,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下
    2023-02-02
  • Java中的排序与内部比较器Compareable解析

    Java中的排序与内部比较器Compareable解析

    这篇文章主要介绍了Java中的排序与内部比较器Compareable解析,一般没有特殊要求时,直接调用(底层默认的升序排列)就可以得到想要的结果,所谓的 sort 方法排序底层都是基于这两种排序,故如果需要设计成所想要的排序就需要了解底层排序原理,需要的朋友可以参考下
    2023-11-11
  • SpringBoot中的Bean装配详解

    SpringBoot中的Bean装配详解

    Spring IoC 容器是一个管理 Bean 的容器,在 Spring 的定义中,它要求所有的 IoC 容器都需要实现接口 BeanFactory,它是一个顶级容器接口,这篇文章主要介绍了SpringBoot中的Bean装配详解,需要的朋友可以参考下
    2024-04-04
  • 基于@MapperScan和@ComponentScan的使用区别

    基于@MapperScan和@ComponentScan的使用区别

    这篇文章主要介绍了@MapperScan和@ComponentScan的使用区别,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • IDEA切换JDK版本详细教程(超管用)

    IDEA切换JDK版本详细教程(超管用)

    在我们项目开发的过程中可能会遇到JDK版本过高或者过低导致一些程序无法启动,不兼容的问题,所以我们需要切换JDK的版本号,这篇文章主要给大家介绍了关于IDEA切换JDK版本的相关资料,需要的朋友可以参考下
    2023-10-10
  • maven安装与环境配置图文教程

    maven安装与环境配置图文教程

    这篇文章主要为大家详细介绍了maven安装与环境配置图文教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-10-10
  • 在已经使用mybatis的项目里引入mybatis-plus,结果不能共存的解决

    在已经使用mybatis的项目里引入mybatis-plus,结果不能共存的解决

    这篇文章主要介绍了在已经使用mybatis的项目里引入mybatis-plus,结果不能共存的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • SpringBoot整合Security实现权限控制框架(案例详解)

    SpringBoot整合Security实现权限控制框架(案例详解)

    Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框,是一个重量级的安全管理框架,本文给大家介绍的非常详细,需要的朋友参考下吧
    2021-08-08

最新评论