[TOC]
本文目的 学习和记录SpringBoot项目中如何配置拦截器,以及如何使用拦截器机型权限控制。
拦截器 拦截器主要用来拦截各种请求并在拦截器中进行相应的处理,一般情况下用来进行权限校验,拦截登录转发,统一日志打印等操作。
拦截器有两种形式:
实现HandlerInterceptor 继承HandlerInterceptorAdapter 使用场景 利用拦截器对多个菜单进行权限控制,只有勾选指定权限的人才能够查看该列表全部数据,其他的必须数据某限定条件才能够进行查询。
考虑到如果在每个菜单控制器中对参数和指定权限进行过滤和控制的话,改动文件太多并且重复代码太多,所以使用拦截器对指定路径的请求进行拦截,在拦截器中记性统一处理,那么只在新增加的类中操作就能实现所有指定菜单的权限控制。
实现代码 自定义拦截器类 实现HandlerInterceptor 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 @Component @Slf4j public class QueryBlackControlInterceptor implements HandlerInterceptor { @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 ; } @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 { } }
继承HandlerInterceptorAdapter 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 @Component @Slf4j public class QueryBlackControlInterceptor implements HandlerInterceptor { @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
就可以了,所以选择继承的方式完成。
自定义拦截器配置类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 @Configuration public class QueryBlackControlConfig extends WebMvcConfigurerAdapter { @Autowired private QueryBlackControlInterceptor queryBlackControlInterceptor; @Override public void addInterceptors (InterceptorRegistry registry) { registry.addInterceptor(queryBlackControlInterceptor).addPathPatterns( "/phoneBlack/getPhoneBlackList" , "/idCardNumBlack/getIdCardNumBlackList" ); } }
查看结果 本地测试进行三次请求(1.没有权限,没有参数、2.没有权限,有参数、3.有权限,没有参数)
1 http://127.0.0.1:8111/phoneBlack/getPhoneBlackList
控制台打印结果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 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 黑名单权限通过
尾言 所有请求都会走拦截器,但是只会拦截配置的请求路径,一般拦截器做的最普遍的就是全部拦截,放开静态文件和登录也之类的操作。
草色烟光残照里,无言谁会凭阑意