Springboot过滤器的几种配置方法

过滤器

直接注入Fiter的方法

Filter

Filter+FiterConfig的方法

Fiter

FilterConfig

SpringSecurity中继承OncePerRequestFilter的方法

直接注入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 filterRegistrationBean = new FilterRegistrationBean<>();

// 设置过滤器

filterRegistrationBean.setFilter(myFilter()); // 过滤器名称

filterRegistrationBean.setName("myFilter"); // 设置名称

filterRegistrationBean.setOrder(1); // 拦截器优先级

//拦截路径集合

ArrayList 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);

}

发表评论
留言与评论(共有 0 条评论) “”
   
验证码:

相关文章

推荐文章