Springboot过滤器的几种配置方法
过滤器直接注入Fiter的方法FilterFilter+FiterConfig的方法FiterFilterConfigSpringSecurity中继承OncePerRequestFilter的方法直接注入Fiter的方法Filterpackage com.doria.learnProject.codeStyle.Filter;import com.alibaba.fastjson.JSONObj
·
过滤器
直接注入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);
}
更多推荐
已为社区贡献9条内容
所有评论(0)