Spring拦截器实现鉴权的示例代码

 更新时间:2023年07月14日 16:35:47   作者:Zayn~  
本文主要介绍了Spring拦截器实现鉴权的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

什么是拦截器?

拦截器(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注册。

/**
 * 拦截器注册 WebConfig
 *
 */
@Configuration
@Slf4j
public class WebConfig implements WebMvcConfigurer {
    /**
     * 登录/权限拦截器
     */
    @Resource
    private CombinedLoginInterceptor combinedLoginInterceptor;
    /**
     * 控制层切面处理
     * ControllerExceptionHandler
     */
    @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";
    /**
     * 无需权限验证的URI集合
     */
    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<HandlerExceptionResolver> resolvers) {
        resolvers.add(controllerExceptionResolver);
    }
}

2、通过XML文件注册

    <!-- 单点登录拦截器配置-->
    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="com.xxx.intercepter.SecurityInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>

除了使用拦截器鉴权,还可以有哪几种方式?

1、传统AOP方式:在Controller方法前添加切点,然后再对切点进行处理即可。

2、过滤器:其实现相对简单,只需要实现Filter接口即可。

详细实现可以参考这篇文章: SpringBoot 项目鉴权的 4 种方式

到此这篇关于Spring拦截器实现鉴权的示例代码的文章就介绍到这了,更多相关Spring拦截器鉴权内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Kotlin中的抽象类实现

    Kotlin中的抽象类实现

    这篇文章主要介绍了Kotlin中的抽象类实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-11-11
  • 使用SpringBoot代码详细解释<List>的用法

    使用SpringBoot代码详细解释<List>的用法

    List是Java集合框架中的一种数据结构,用于存储一组有序的元素,使用List可以方便地向其中添加、删除或者修改元素,也可以通过下标或者迭代器遍历其中的元素,这篇文章主要介绍了用SpringBoot代码详细解释<List>的用法,需要的朋友可以参考下
    2023-09-09
  • Java数据结构之单链表的实现与面试题汇总

    Java数据结构之单链表的实现与面试题汇总

    由于顺序表的插入删除操作需要移动大量的元素,影响了运行效率,因此引入了线性表的链式存储——单链表。本文为大家介绍了单链表的实现与面试题汇总,感兴趣的可以了解一下
    2022-10-10
  • JavaWeb案例讲解Servlet常用对象

    JavaWeb案例讲解Servlet常用对象

    Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层
    2021-10-10
  • SpringBoot集成WebServlet出现自定义servlet请求失败的问题解决方案

    SpringBoot集成WebServlet出现自定义servlet请求失败的问题解决方案

    SpringBoot中以Bean方式注册Servlet时遇到的问题,通过了解DispatcherServlet的原理,发现默认路径冲突是主要原因,本文介绍SpringBoot集成WebServlet出现自定义servlet请求失败的问题解决方案,感兴趣的朋友一起看看吧
    2025-03-03
  • SpringBoot快速迁移至Quarkus的方法步骤

    SpringBoot快速迁移至Quarkus的方法步骤

    这篇文章主要介绍了SpringBoot快速迁移至Quarkus的方法步骤。文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • java程序如何启动新的进程

    java程序如何启动新的进程

    这篇文章主要介绍了java程序如何启动新的进程问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-05-05
  • 使用SpringBoot+AOP实现可插拔式日志的示例代码

    使用SpringBoot+AOP实现可插拔式日志的示例代码

    这篇文章主要介绍了使用SpringBoot+AOP实现可插拔式日志的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-07-07
  • 基于StringBuilder类中的重要方法(介绍)

    基于StringBuilder类中的重要方法(介绍)

    下面小编就为大家带来一篇基于StringBuilder类中的重要方法(介绍)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07
  • Druid核心源码解析DruidDataSource

    Druid核心源码解析DruidDataSource

    这篇文章主要为大家介绍了Druid核心源码解析DruidDataSource,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-03-03

最新评论