Spring拦截器实现鉴权的示例代码
admin
2024-04-02 17:21
什么是拦截器?
拦截器(Interceptor)类似于Servlet中的过滤器,主要用于拦截用户请求并做出相应的处理,例如拦截器可以进行权限验证、记录请求信息的日志、判断用户是否登录等。拦截器允许自定义预处理(Pre-Processing),在其中可以选择禁止对应Handler 的执行;也允许自定义后处理(Post-Precessing);
怎样实现Spring拦截器?
实现Spring拦截器很简单,只需要实现HandlerInterceptor接口即可。HandlerInterceptor这个接口中有三个核心方法:
1.preHandle方法:在HandlerMapping确定Handler对象之后,但在HandlerAdapter调用handler之前执行(就是在调用controller之前执行该方法)。该方法返回一个布尔值,只有true的时候才继续执行对应的handler,否则不再执行对应的handler了。
default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
return true;
}
2.postHandle方法:在 HandlerAdapter 实际调用处理程序之后,但在 DispatcherServlet 呈现视图之前调用(就是在响应返回客户端之前执行)。
default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {}
3.afterCompletion方法:请求处理完成后回调,即渲染视图后。将在处理程序执行的任何结果上被调用,从而允许适当的资源清理。注意:只有当这个拦截器的 preHandle 方法成功完成并返回 true 时才会被调用!与 postHandle 方法一样,该方法将以相反的顺序在链中的每个拦截器上调用,因此第一个拦截器将是最后一个被调用的。
default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {}
}
关于上述三个核心方法调用的顺序,在此我们假设有是三个拦截器,Interceptor1 、Interceptor2、和Interceptor3。在定义三个拦截器的时候我们就是按照这个顺序定义的,而拦截器的执行顺序就是按照之前定义的顺序执行。
Interceptor1的preHandle方法 -> Interceptor2的preHandle方法 -> Interceptor3的preHandle方法 -> controller ->Interceptor3 的postHandle方法 -> Interceptor2 的postHandle方法 -> Interceptor1 的postHandle方法 -> Interceptor3 的afterCompletion方法 -> Interceptor2 的afterCompletion方法 ->Interceptor1 的afterCompletion方法。如图:
如何使用Spring拦截器鉴权?
通过上述对三个核心方法的解释可知,如果我们想通过拦截器实现鉴权,那么只需要实现接口后,在preHandle方法中做相应的处理即可。如下:
public class SecurityInterceptor implements HandlerInterceptor {
@Autowired
private JddPmsHelper jddPmsHelper;
@Value("${global.authTest}")
private String authTest;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//测试环境不校验权限,需预发验证
if ("true".equals(authTest)) {
return true;
}
String uri = request.getRequestURI();
if (uri.contains("static")) {
return true;
}
String pin = ServletUtils.getCommonPin();
if (StringUtils.isBlank(pin)) {
throw new NoLoginException("未登陆");
}
if (uri.equals("/")) {
return true;
}
boolean checkResult = jddPmsHelper.authCheckUrl(pin, uri);
if (!checkResult) {
throw new NoneSecurityException("您没有权限访问,请联系管理员,对您的erp账号进行配置");
}
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
在实现HandlerInterceptor接口之后,可以通过
1、拦截器注册:实现WebMvcConfigurer的addInterceptors注册。
@Configuration
@Slf4j
public class WebConfig implements WebMvcConfigurer {
@Resource
private CombinedLoginInterceptor combinedLoginInterceptor;
@Resource
private ControllerExceptionResolver controllerExceptionResolver;
private static final String MATCH_ALL = "
private static final String APP_EXCLUDE = "/common/info";
private static final String ERROR_URL = "/error";
private static final String[] PC_WHITE_LIST = {APP_EXCLUDE, ERROR_URL};
@Override
public void addInterceptors(InterceptorRegistry registry) {
//PC端登录拦截,必须添加
registry.addInterceptor(combinedLoginInterceptor).addPathPatterns(MATCH_ALL).excludePathPatterns(PC_WHITE_LIST).order(1);
}
@Override
public void configureHandlerExceptionResolvers(List resolvers) {
resolvers.add(controllerExceptionResolver);
}
}
2、通过XML文件注册
除了使用拦截器鉴权,还可以有哪几种方式?
1、传统AOP方式:在Controller方法前添加切点,然后再对切点进行处理即可。
2、过滤器:其实现相对简单,只需要实现Filter接口即可。
详细实现可以参考这篇文章: SpringBoot 项目鉴权的 4 种方式
到此这篇关于Spring拦截器实现鉴权的示例代码的文章就介绍到这了,更多相关Spring拦截器鉴权内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341