filter鉴权

filter原理

filter是Java Servlet规范中的一个组件,用于拦截和处理HTTP请求和响应。它是一种服务器端的组件,可以在请求到达Servlet之前或响应返回给客户端之前对请求和响应进行拦截和处理。

filter的全部生命周期如下:

  • ​初始化:通过init()方法加载配置。
  • ​执行:每次请求触发doFilter()方法。
  • ​销毁:通过destroy()方法释放资源。

接口

在java中使用filter需要实现javax.servlet.Filter接口


public class EncodingFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        chain.doFilter(request, response); // 传递请求
    }
}

调用和扩展filter接口的本质就是重写doFilter()方法,然后调用chain.doFilter()传递请求。

多个Filter按配置顺序形成链式处理,顺序由web.xml中的声明顺序或注解的类名决定。

绕过

在Java中通常会使用request.getRequestURL()和request.getRequestURI()这两个方法获取请求路径,然后对请求路径做校验。

例子如下

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        HttpServletRequest request = (HttpServletRequest) req;

        String uri = request.getRequestURI();
        StringBuffer requestURL = request.getRequestURL();
        System.out.println(requestURL);
        if(uri.startsWith("/system/login")) {  //登陆接口设置⽩白名单,即登录页面
            System.out.println("login_page");
            resp.getWriter(). write("login_page");

            chain.doFilter(request, resp);
        }
        else if(uri.endsWith(".do")||uri.endsWith(".action")) {
//检测当前⽤户是否登陆
            User user =(User) request.getSession().getAttribute("user");
            if(user == null) {
                resp.getWriter(). write("unauthorized access"); //未授权访问
                System.out.println("unauthorized access");
                resp.getWriter(). write("go to login_page");//跳转登录
                System.out.println("go to login_page");
            }
        }
    }

例子使用了request的startsWith方法来判断URL是否以/system/login开头,endsWith方法来判断URL是否以.do或.action结尾。

那么常见的绕过方式有以下几种:

../绕过

这个类似于读写路径中返回上一层文件关系的用法。

例如/system/login/../的结果实际上就是/system/,因此在这里使用../绕过可以这样构造:

/system/login/../../login/main.do

例题

还在攻克中…