Springboot - filter

Springboot - filter

Springboot's filter can filter specified urls in web development,
such as intercepting interface requests we don't need, and can also modify request and response content.
Application scenarios of filters:
1) Filter sensitive words (prevent sql injection)
2 ) Set character encoding
3) URL-level permission access control
4) Compress response information

We use a demo to explain the scenario that needs to be implemented: intercept all web interfaces through filters, except for whitelist interfaces and internal interfaces that pass unconditionally, all other interfaces need to be verified by token

1. Custom Filters

The filter needs to implement the Filter class, which has three default methods (init initial method, doFilter core filtering method, destroy destruction method)

/**
 * @description:
 * @author: 梦想的边缘
 * @create: 2021/08/11 10:44
 */
public class BaseFilter implements Filter {
    
    
    Logger logger = LoggerFactory.getLogger(BaseFilter.class);

    static final String TOKEN = "20220423344556abac";
    
    //内部接口集合
    public static List<String> INSIDE_URLS = Lists.newArrayList("/index","/inside");
    //白名单接口集合
    public static List<String> WHITE_PATH = Lists.newArrayList("/white","/login");


    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    
    
        logger.info("初始化数据");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    
    
        HttpServletResponseWrapper wrapper = new HttpServletResponseWrapper((HttpServletResponse)servletResponse);
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        String requestURI = request.getRequestURI();
        if(INSIDE_URLS.contains(requestURI)){
    
    
            //内部接口,直接通过
            filterChain.doFilter(servletRequest,servletResponse);
            return;
        }
        if(WHITE_PATH.contains(requestURI)){
    
    
            //白名单接口,直接通过
            filterChain.doFilter(servletRequest,servletResponse);
            return;
        }
        //进行校验,如token校验
        String token = request.getHeader("token");
        if(TOKEN.equals(token)){
    
    
            filterChain.doFilter(servletRequest,servletResponse);
        }else {
    
    
            //token校验不通过,重定向到登录页面
            wrapper.sendRedirect("/login");
        }

    }

    @Override
    public void destroy() {
    
    
    }
}

2. Filter configuration class


/**
 * @description:
 * @author: 梦想的边缘
 * @create: 2021/08/11 10:39
 */
@Configuration
public class FilterConfig {
    
    
    /**
     * 基础过滤器
     * @return
     */
    @Bean
    public FilterRegistrationBean<Filter> baseFilter(){
    
    
        FilterRegistrationBean<Filter> filterRegistrationBean = new FilterRegistrationBean();
        filterRegistrationBean.setFilter(new BaseFilter());
        filterRegistrationBean.setUrlPatterns(Lists.newArrayList("/*"));
        filterRegistrationBean.setOrder(1);
        return filterRegistrationBean;
    }
}

In order to cooperate with the test, we add the controller method and the login page login.html
interface:

/**
 * @description:
 * @author: 梦想的边缘
 * @create: 2021/08/01 23:37
 */
@RestController
public class restController {
    
    

    @Autowired
    private AsynService asynService;
    /**
     * 白名单接口
     * @return
     */
    @GetMapping("/while")
    public String whileTest(){
    
    
        return "success";
    }

    /**
     * 非白名单接口
     * @return
     */
    @GetMapping("/no-while")
    public String noWhileTest(){
    
    
        return "success";
    }

    /**
     * 登录接口
     * @param username
     * @param password
     * @param mv
     * @param request
     * @param model
     * @return
     */
    @GetMapping("/login")
    public ModelAndView login(String username, String password, ModelAndView mv, HttpServletRequest request, Model model){
    
    
        if(StringUtils.hasLength(username)&&StringUtils.hasLength(password)){
    
    
            //TODO 登录逻辑
            System.out.println("成功!!");
            mv.setViewName("index");
        }else{
    
    
            System.out.println("失败!!");
            mv.setViewName("/login.html");
        }
        return mv;
    }
}

login.html

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>登录测试页面</title>
    <link rel="stylesheet" href="css/style.css"/>
    <style>
        #parent{
    
    
            width:500px;
            height:200px;
            margin-top:20%;
            margin-left:50%;
            transform:translate(-50%,-50%) ;
            background:#009688;
        }
        .password,.subBtn{
    
    
            margin-top: 2%;
            margin-left: 3%;
        }
        .loginHeader{
    
    
            padding-top: 1%;
        }
    </style>
</head>
<body class="login_bg">
<div id="parent">
    <section class="loginBox">
        <header class="loginHeader" style="text-align:center; ">
            <h1>登录测试页面</h1>
        </header>
        <section class="loginCont">
            <form class="loginForm" action="/user/login" method="post" onsubmit="return check()" >
                <div class="inputbox"  style="text-align:center; ">
                    <label for="user">用户名:</label>
                    <input id="user" type="text" name="userName" placeholder="请输入用户名" required="required" />
                </div>
                <div class="password"  style="text-align:center; " >
                    <label for="mima">密码:</label>
                    <input id="mima" type="password" name="password" placeholder="请输入密码" required="required" />
                </div>
                <div class="subBtn"  style="text-align:center; ">
                    <input type="submit" value="登录" />
                    <input type="reset" value="重置"/>
                </div>
            </form>
        </section>
    </section>
</div>
</body>
</html>

3. Test

After the project starts, visit the following two interfaces (whitelist interface PK non-whitelist interface)
interface one: http://localhost:8080/whileTest
interface two: http://localhost:8080/no-while

Interface 1 is a whitelist category, the filter passes through directly, and returns "success", as shown in the figure below:
insert image description here

Interface 2 needs to verify the token in the filter. If the token is not carried, it will redirect to the login page

---------Publisher: Edge of Dreams

Guess you like

Origin blog.csdn.net/gsycwh/article/details/119620618