最近工作中,遇到一个需求,需要将某一个具体按钮收口到某一个人,于是就有了今天的记录。
思路就是: 1、创建注解,用于控制拦截的路径,以及是否拦截; 2、创建拦截器,在preHandler 里面 获取用户信息,然后判断用户信息是否具有某一权限或者是具有某一方法的执行权限(方法都是绑定到某一具体按钮的 所以方法的权限就相当于是按钮的权限) 3、配置拦截器,将拦截器添加,并添加具体拦截的访问路径,交由Spring管理。
首先创建自定义注解
/** * @Author yanjun * @Date 2021/11/18 10:12 * 自定义注解 用于实现权限控制 */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface AuthorizedLimit { /** * 是否拦截 */ boolean limit() default true; /** * 资源路径 */ String resourcePath(); }
在需要拦截的按钮触发的方法Controller上添加注解@AuthorizedLimit(resourcePath="")
如下
@PostMapping("/aaa") @AuthorizedLimit(resourcePath = "/aaa")
创建拦截器适配器 执行具体逻辑
/** * @Author yanjun * @Date 2021/11/18 10:24 * <p> * 拦截器适配器 * 判断用户是否是需要拦截 */ @Component public class AuthorizedInterceptor extends HandlerInterceptorAdapter { private Logger logger = LoggerFactory.getLogger(AuthorizedInterceptor.class); @Autowired private AuthorizationHelper authorizationHelper; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (!(handler instanceof HandlerMethod)) { return super.preHandle(request, response, handler); } HandlerMethod method = ((HandlerMethod) handler); AuthorizedLimit authorizedLimit = method.getMethodAnnotation(AuthorizedLimit.class); /** * 判断注解不为空 且标注该注解的方法被拦截 */ if (null != authorizedLimit && authorizedLimit.limit()) { //获取登陆人信息 String userName = "yanjun"; //获取资源路径 String resourcePath = authorizedLimit.resourcePath(); if (!authorizationHelper.hasResourceAuthorized(userName, resourcePath)) { noPermission( response); return false; } else { return true; } } return false; } /** * 没有权限的处理方式 * @param response */ private void noPermission(HttpServletResponse response) { try { /*设置响应头编码格式*/ response.setHeader("Content-Type","text/html;charset=utf-8"); OutputStream out = response.getOutputStream(); JSONObject dealMsg= new JSONObject(); dealMsg.put("code", 403); dealMsg.put("msg", "抱歉,您没有访问权限,请联系"+"【xxx】"); out.write(dealMsg.toJSONString().getBytes()); out.flush(); //关流 out.close(); } catch (IOException e) { logger.error(LogUtil.formatLog("AuthorizedInterceptor", "noPermission", "noPermissionError", "", "", "处理权限出错!"), e); } } }
创建帮助类 用于判断 用户是否具有某一权限
/** * @Author yanjun * @Date 2021/11/18 10:26 * 判断用户是否具有某一权限 */ @Component public class AuthorizationHelper { /** * 判断用户是否具有某一资源路径的方法 * @param userName 用户名 * @param resourcePath 资源路径 * @return */ public boolean hasResourceAuthorized(String userName,String resourcePath){ if(StringUtils.isEmpty(userName) || StringUtils.isEmpty(resourcePath)){ return false; } /** * 判断用户是否是某一指定用户 */ if(userName.equals("yanjun") && resourcePath.equals("/aaa")){ return true; }else { return false; } } }
最后 将拦截器注册
/** * @Author yanjun * @Date 2021/11/18 11:12 * 配置拦截器 拦截请求 */ @Configuration public class AuthorizedLimitConfig extends WebMvcConfigurer { /** * 将拦截器添加 * @param registry */ @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(getAuthorizedInterceptor()).addPathPatterns("/rule-module-config/updateState"); } /** * 获取自定义拦截器 * @return */ @Bean AuthorizedInterceptor getAuthorizedInterceptor(){ return new AuthorizedInterceptor(); } }