SpringBoot中如何使用拦截器实现权限控制进行记录和说明

各位看官可以关注博主个人博客,了解更多信息。
作者:Surpasser
链接地址:https://www.surpass.org.cn

本文目的

学习和记录SpringBoot项目中如何配置拦截器,以及如何使用拦截器机型权限控制。

拦截器

​ 拦截器主要用来拦截各种请求并在拦截器中进行相应的处理,一般情况下用来进行权限校验,拦截登录转发,统一日志打印等操作。

​ 拦截器有两种形式:

  1. 实现HandlerInterceptor
  2. 继承HandlerInterceptorAdapter

使用场景

利用拦截器对多个菜单进行权限控制,只有勾选指定权限的人才能够查看该列表全部数据,其他的必须数据某限定条件才能够进行查询。

考虑到如果在每个菜单控制器中对参数和指定权限进行过滤和控制的话,改动文件太多并且重复代码太多,所以使用拦截器对指定路径的请求进行拦截,在拦截器中记性统一处理,那么只在新增加的类中操作就能实现所有指定菜单的权限控制。

实现代码

自定义拦截器类

实现HandlerInterceptor

//交给Spring管理
@Component
//日志打印
@Slf4j
public class QueryBlackControlInterceptor implements HandlerInterceptor {

    /**
     * @Description: 控制校验是否拥有查看全部的权限,没有则必须携带指定参数访问
     * @Description: 在进入控制器前执行此操作
     * @param request
     * @param response
     * @param handler
     * @return boolean
     * @author Surpass
     * @date 2020/12/8 18:01
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
                             Object handler) throws Exception {
        log.info("黑名单权限校验拦截器");
        log.info("request请求地址path[{}] uri[{}] url[{}]", request.getServletPath(),
                request.getRequestURI(),request.getRequestURL());
        Subject subject = SecurityUtils.getSubject();
        //是否具有查看全部的权限
        boolean blacklistMenuControl = subject.isPermitted("queryALLBlack:view");
        log.info("是否存在查看全部的权限:{}",blacklistMenuControl);

        if (!blacklistMenuControl){
            //没有权限判断是否存在指定的查询条件
            //返回路径
            String url = null;
            //提示语
            String alert = null;
            Map<String, String[]> parameterMap = request.getParameterMap();
            Set<Map.Entry<String, String[]>> entries = parameterMap.entrySet();

            //匹配黑名单菜单
            for (Map.Entry<String, String[]> entry : entries) {
                String key = entry.getKey();
                String[] value = entry.getValue();
                if (Objects.equals(key, "phone")){
                    if (StringUtils.isBlank(value[0])){
                        url = "/phoneBlack/getPhoneBlack";
                        alert = "请输入手机号";
                    }
                    break;
                }
                if (Objects.equals(key, "idCardNum")){
                    if (StringUtils.isBlank(value[0])){
                        url = "/idCardNumBlack/getIdCardNumBlack";
                        alert = "请输入身份证号";
                    }
                    break;
                }

            //是否存在需要返回的内容
            if (StringUtils.isNotBlank(url) && StringUtils.isNotBlank(alert)) {
                log.info("黑名单查询校验不通过");
                response.setContentType("text/html; charset=utf-8");
                PrintWriter writer = response.getWriter();
                writer.println("<script language='javascript'>");
                writer.println("window.location.href = '"+url+"';");
                writer.println("alert('"+alert+"');");
                writer.println("</script>");
                return false;
            }
        }
        log.info("黑名单权限通过");
        return true;
    }

    /**
     * @Description: 在执行完控制器之后,视图渲染之前执行此操作
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    /**
     * @Description: 在试图渲染之后执行此操作
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
                                Object handler, Exception ex) throws Exception {

    }
}

继承HandlerInterceptorAdapter

//交给Spring管理
@Component
//日志打印
@Slf4j
public class QueryBlackControlInterceptor implements HandlerInterceptor {

    /**
     * @Description: 控制校验是否拥有查看全部的权限,没有则必须携带指定参数访问
     * @Description: 在进入控制器前执行此操作
     * @param request
     * @param response
     * @param handler
     * @return boolean
     * @author Surpass
     * @date 2020/12/8 18:01
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
                             Object handler) throws Exception {
        log.info("黑名单权限校验拦截器");
        log.info("request请求地址path[{}] uri[{}] url[{}]", request.getServletPath(),
                request.getRequestURI(),request.getRequestURL());
        Subject subject = SecurityUtils.getSubject();
        //是否具有查看全部的权限
        boolean blacklistMenuControl = subject.isPermitted("queryALLBlack:view");
        log.info("是否存在查看全部的权限:{}",blacklistMenuControl);

        if (!blacklistMenuControl){
            //没有权限判断是否存在指定的查询条件
            //返回路径
            String url = null;
            //提示语
            String alert = null;
            Map<String, String[]> parameterMap = request.getParameterMap();
            Set<Map.Entry<String, String[]>> entries = parameterMap.entrySet();

            //匹配黑名单菜单(只需要在这里根据菜单返回不同的信息和路径就可以了)
            for (Map.Entry<String, String[]> entry : entries) {
                String key = entry.getKey();
                String[] value = entry.getValue();
                if (Objects.equals(key, "phone")){
                    if (StringUtils.isBlank(value[0])){
                        url = "/phoneBlack/getPhoneBlack";
                        alert = "请输入手机号";
                    }
                    break;
                }
                if (Objects.equals(key, "idCardNum")){
                    if (StringUtils.isBlank(value[0])){
                        url = "/idCardNumBlack/getIdCardNumBlack";
                        alert = "请输入身份证号";
                    }
                    break;
                }

            //是否存在需要返回的内容
            if (StringUtils.isNotBlank(url) && StringUtils.isNotBlank(alert)) {
                log.info("黑名单查询校验不通过");
                response.setContentType("text/html; charset=utf-8");
                PrintWriter writer = response.getWriter();
                writer.println("<script language='javascript'>");
                writer.println("window.location.href = '"+url+"';");
                writer.println("alert('"+alert+"');");
                writer.println("</script>");
                return false;
            }
        }
        log.info("黑名单权限通过");
        return true;
    }
}

说明:这里对权限控制只需要用到 preHandle 就可以了,所以选择继承的方式完成。(少几行代码)

自定义拦截器配置类

@Configuration
public class QueryBlackControlConfig extends WebMvcConfigurerAdapter {

    //注入拦截器类
    @Autowired
    private QueryBlackControlInterceptor queryBlackControlInterceptor;

    /**
     * @Description: 拦截菜单权限控制路径(拦截菜单很多,这里举两个例子)
     * @param registry
     * @return void
     * @author Surpass
     * @date 2020/12/8 17:59
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //可变参数长度(需要被拦截的请求路径)
        //将拦截器类注册到配置中
        registry.addInterceptor(queryBlackControlInterceptor).addPathPatterns(
                "/phoneBlack/getPhoneBlackList",
                "/idCardNumBlack/getIdCardNumBlackList");
    }
}

查看结果

本地测试进行三次请求(1.没有权限,没有参数、2.没有权限,有参数、3.有权限,没有参数)

http://127.0.0.1:8111/phoneBlack/getPhoneBlackList

控制台打印结果

INFO 2020-12-15 16:23:04.440 黑名单权限校验拦截器
INFO 2020-12-15 16:23:04.440 request请求地址url[http://127.0.0.1:8111/phoneBlack/getPhoneBlackList]
INFO 2020-12-15 16:23:04.451 是否存在查看全部的权限:false
INFO 2020-12-15 16:23:40.440 黑名单查询校验不通过

INFO 2020-12-15 16:25:10.922 黑名单权限校验拦截器
INFO 2020-12-15 16:25:10.922 request请求地址url[http://127.0.0.1:8111/phoneBlack/getPhoneBlackList]
INFO 2020-12-15 16:25:10.929 是否存在查看全部的权限:false
INFO 2020-12-15 16:25:10.929 黑名单权限通过

INFO 2020-12-15 16:27:20.964 黑名单权限校验拦截器
INFO 2020-12-15 16:27:20.964 request请求地址url[http://127.0.0.1:8111/phoneBlack/getPhoneBlackList]
INFO 2020-12-15 16:27:20.971 是否存在查看全部的权限:true
INFO 2020-12-15 16:27:20.972 黑名单权限通过

尾言

所有请求都会走拦截器,但是只会拦截配置的请求路径,一般拦截器做的最普遍的就是全部拦截,放开静态文件和登录也之类的操作。

草色烟光残照里,无言谁会凭阑意

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Spring Boot实现拦截器的过程可以参考提供的详细示例代码解析。在Spring Boot,可以通过创建一个自定义的拦截器类来实现拦截功能拦截器类需要实现Spring框架的HandlerInterceptor接口,并重写其的方法。 首先,需要创建一个拦截器类,该类需要实现HandlerInterceptor接口,并重写其的preHandle、postHandle和afterCompletion方法。preHandle方法在请求处理之前执行,可以用于进行权限验证、日志记录等操作;postHandle方法在请求处理之后执行,可以对响应结果进行处理;afterCompletion方法在视图渲染之后执行,可以进行一些资源的清理操作。 接下来,需要在Spring Boot应用程序的配置类(通常是带有@SpringBootApplication注解的类)注册拦截器。可以通过重写WebMvcConfigurer接口的addInterceptors方法来实现。在该方法,可以使用addInterceptor方法将自定义的拦截器类添加到拦截器,指定需要拦截的路径或排除的路径。 通过以上步骤,就可以实现拦截器Spring Boot应用使用了。拦截器会在请求到达控制器方法之前进行拦截,并执行拦截器定义的相关逻辑。 需要注意的是,拦截器Spring Boot是针对Spring MVC的访问进行增强的,与Servlet技术的过滤器(Filter)有所区别。拦截器通过动态拦截方法调用的机制来实现,而过滤器对所有访问进行增强。<span class="em">1</span><span class="em">2</span><span class="em">3</span><span class="em">4</span>

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值