Spring如何编写一个拦截器实现鉴权呢?

重生 Spring 发布时间:2024-01-04 21:50:19 阅读数:2445 1
下文笔者讲述Spring编写拦截器实现是否登录的验证分享,如下所示

拦截器简介

拦截器(Interceptor):
  相当于Servlet中的过滤器

拦截器的功能:
   用于拦截用户请求并做出相应的处理

 如:
   拦截器可以进行权限验证、记录请求信息的日志、判断用户是否登录等
   拦截器允许自定义预处理(Pre-Processing)
    在其中可以选择禁止对应Handler运行
    也允许自定义后处理(Post-Precessing)

Spring拦截器的实现思路

我们可以通过实现 HandlerInterceptor接口 
    并重写其中的核心方法,采用这种方法可编写Spring中的拦截器

=============================================================

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方法
例:拦截器实现鉴权
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 {
    }
}

拦截器注册

/**
 * 拦截器注册 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);
    }
}
或 使用xml注册
<!-- 单点登录拦截器配置-->
<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <bean class="com.xxx.intercepter.SecurityInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>
版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。

本文链接: https://www.Java265.com/JavaFramework/Spring/202401/7623.html

最近发表

热门文章

好文推荐

Java265.com

https://www.java265.com

站长统计|粤ICP备14097017号-3

Powered By Java265.com信息维护小组

使用手机扫描二维码

关注我们看更多资讯

java爱好者