直接注入Fiter的方法

Filter

package com.doria.learnProject.codeStyle.Filter;

import com.alibaba.fastjson.JSONObject;
import com.doria.common.pojo.vo.HttpResult;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@Component // 将拦截器放入容器,自然会生效
@Order(2) // 设置拦截器的优先级,数字越小,越先执行
public class TokenFilter implements Filter {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("过滤器执行");
        HttpServletRequest req = (HttpServletRequest) servletRequest;
        HttpServletResponse resp = (HttpServletResponse) servletResponse;
        String token = req.getHeader("Authorization");
        if (StringUtils.isBlank(token)){
            resp.setContentType("application/json;charset=UTF-8");
            PrintWriter writer = resp.getWriter();
            resp.setStatus(401);
            HttpResult<?> result = new HttpResult<>();
            result.setFlag(false);
            result.setMessage("缺少token");
            result.setCode(401001);
            writer.write(JSONObject.toJSONString(result));
            writer.flush();
            writer.close();
        }else {
            filterChain.doFilter(servletRequest, servletResponse);
        }
    }

    @Override
    public void destroy() {

    }
}

Filter+FiterConfig的方法

Fiter

 
import org.springframework.context.annotation.Configuration;
 
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
 
public class MyFilter implements Filter {
 
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse resp = (HttpServletResponse) response;
        HttpServletRequest res = (HttpServletRequest) request;
        System.out.println("当前过滤到的路径:"+res.getRequestURI());
        /**
         * 这是的代码是为了前后分离 允许跨域
         */
        resp.setHeader("Access-Control-Allow-Origin","*");
        resp.setHeader("Access-Control-Allow-Credentials", "true");
        resp.setHeader("Access-Control-Allow-Methods", "POST, GET, PATCH, DELETE, PUT");
        resp.setHeader("Access-Control-Max-Age", "3600");
        resp.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
 
        chain.doFilter(request, response);  //放行
        // request.getRequestDispatcher("/api/open/unLogin").forward(request,response); //重定向
    }
 
}

FilterConfig

package com.doria.learnProject.codeStyle.Filter;

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.servlet.Filter;
import javax.servlet.FilterRegistration;
import java.util.ArrayList;

@Configuration
public class FilterConfig {
    
    @Bean
    public Filter myFilter (){
        return new MyFilter ();
    }
    
    @Bean
    public FilterRegistrationBean<?> filterRegistrationBean(){
        FilterRegistrationBean<Filter> filterRegistrationBean = new FilterRegistrationBean<>();

        // 设置过滤器
        filterRegistrationBean.setFilter(myFilter()); // 过滤器名称
        filterRegistrationBean.setName("myFilter"); // 设置名称
        filterRegistrationBean.setOrder(1); // 拦截器优先级

        //拦截路径集合
        ArrayList<String> pathList = new ArrayList<>();
        pathList.add("/*");

        filterRegistrationBean.setUrlPatterns(pathList); // 设置需要拦截的路径
        return filterRegistrationBean;
    }
}

SpringSecurity中继承OncePerRequestFilter的方法

@Component
public class CustomJwtTokenFilter extends OncePerRequestFilter {


    @Resource
    private AuthenticationManager authenticationManager;
    @Resource
    private JwtUtils jwtUtils;


    @Override
    protected void doFilterInternal(HttpServletRequest req, HttpServletResponse resp, FilterChain chain) throws ServletException, IOException {
        log.info("token filter执行了");
        String token = req.getHeader("Authorization");
        if (StringUtils.isNotBlank(token)) {
            // 这里的判定是为了兼容鉴权服务和资源服务的放行,如果是直接访问鉴权和资源的就进行放行,bearer是使用accessToken进行访问时使用的token,basic是资源访问时使用的商户token
            // 资源鉴权分离式中仅需鉴权配置bearer即可,,资源中不需要用户登录所以无需配置此配置
            if (!(token.contains("Basic") || token.contains("basic") ||
                    token.contains("Bearer") || token.contains("bearer"))) {
                User user = jwtUtils.checkToken(token);
                // 不为空再进行安全上下文的生成和赋予;如果为空直接放行,下一个过滤器会收拾他,不过不要修改加解密bean
                UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user.getId(), "success");
                // 手动调用security的校验方法,会调用校验管理员,触发我们定义好的用户加载和加解密校验,传入经过处理的authenticationToken
                Authentication authenticate = authenticationManager.authenticate(authenticationToken);
                // 将获得到的[用户安全上下文]对象设置到[安全上下文持有者]中
                SecurityContextHolder.getContext().setAuthentication(authenticate);
            }
        }
        chain.doFilter(req, resp);
    }
}

排序
 @Override
 protected void configure(HttpSecurity http) throws Exception {
   // 添加jwt过滤器到密码校验之前,在那之前完成jwt的校验和放入安全上下文对象
  http.addFilterBefore(customJwtTokenFilter, UsernamePasswordAuthenticationFilter.class);
}
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐