From 72bb9e92cf52a23bf7f0b973469ae1e6594ff086 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=83=9D=E5=85=88=E7=91=9E?= <1490493387@qq.com> Date: Sun, 31 Jul 2022 15:51:38 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=80=9A=E8=BF=87AOP=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E5=BE=AE=E6=9C=8D=E5=8A=A1API=E8=AF=B7=E6=B1=82=E6=96=B9?= =?UTF-8?q?=E6=B3=95=E7=9A=84=E9=89=B4=E6=9D=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/controller/SysUserController.java | 2 + .../web/security/advice/PermissionAdvice.java | 90 +++++++++++++++++++ .../web/security/annotation/RequirePerms.java | 19 ++++ .../main/resources/META-INF/spring.factories | 3 +- 4 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 youlai-common/common-web/src/main/java/com/youlai/common/web/security/advice/PermissionAdvice.java create mode 100644 youlai-common/common-web/src/main/java/com/youlai/common/web/security/annotation/RequirePerms.java diff --git a/youlai-admin/admin-boot/src/main/java/com/youlai/admin/controller/SysUserController.java b/youlai-admin/admin-boot/src/main/java/com/youlai/admin/controller/SysUserController.java index a4ab73768..0f806356e 100644 --- a/youlai-admin/admin-boot/src/main/java/com/youlai/admin/controller/SysUserController.java +++ b/youlai-admin/admin-boot/src/main/java/com/youlai/admin/controller/SysUserController.java @@ -15,6 +15,7 @@ import com.youlai.admin.pojo.vo.user.UserVO; import com.youlai.admin.service.SysUserService; import com.youlai.common.result.PageResult; import com.youlai.common.result.Result; +import com.youlai.common.web.security.annotation.RequirePerms; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; @@ -73,6 +74,7 @@ public class SysUserController { } @ApiOperation(value = "删除用户") + @RequirePerms(value = "sys:user:delete") @DeleteMapping("/{ids}") public Result deleteUsers(@ApiParam("用户ID,多个以英文逗号(,)分割") @PathVariable String ids) { boolean result = userService.deleteUsers(ids); diff --git a/youlai-common/common-web/src/main/java/com/youlai/common/web/security/advice/PermissionAdvice.java b/youlai-common/common-web/src/main/java/com/youlai/common/web/security/advice/PermissionAdvice.java new file mode 100644 index 000000000..6f320aaaf --- /dev/null +++ b/youlai-common/common-web/src/main/java/com/youlai/common/web/security/advice/PermissionAdvice.java @@ -0,0 +1,90 @@ +package com.youlai.common.web.security.advice; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.convert.Convert; +import com.youlai.common.constant.GlobalConstants; +import com.youlai.common.result.Result; +import com.youlai.common.result.ResultCode; +import com.youlai.common.web.security.annotation.RequirePerms; +import com.youlai.common.web.util.UserUtils; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.Map; + +/** + * 权限校验切面 + * + * TODO 整合SpEL表达式 + * + * @author haoxr + * @date 2022/7/30 + */ +@Component +@Aspect +@RequiredArgsConstructor +@Slf4j +public class PermissionAdvice { + + private final RedisTemplate redisTemplate; + + /** + * - + * 权限切点定义 + */ + @Pointcut("@annotation(com.youlai.common.web.security.annotation.RequirePerms)") + public void pointCut() { + } + + @Around("pointCut()") + public Object around(ProceedingJoinPoint joinPoint) throws Throwable { + log.info("permission verification start."); + MethodSignature signature = (MethodSignature) joinPoint.getSignature(); + RequirePerms annotation = signature.getMethod().getAnnotation(RequirePerms.class); + + String[] requiredPerms = annotation.value(); // 需要的权限标识集合 + log.info("required perms :{}", requiredPerms); + + // 权限校验 + boolean passFlag = false; + List userRoles = UserUtils.getRoles(); + + // 超级管理员放行 + if (UserUtils.isRoot()) { + return true; + } + + Map permRolesMap = redisTemplate.opsForHash().entries(GlobalConstants.BTN_PERM_ROLES_KEY); + if (permRolesMap != null) { + for (String requiredPerm : requiredPerms) { + List hasPermRoles = Convert.toList(String.class, permRolesMap.get(requiredPerm)); // 拥有访问权限的角色 + if (CollectionUtil.isNotEmpty(hasPermRoles)) { + for (String hasPermRole : hasPermRoles) { + boolean hasPerm = userRoles.stream().anyMatch(userRole -> userRole.equals(hasPermRole)); + if (hasPerm) { + passFlag = true; + break; + } + } + } + } + } + log.info("authentication result :{}", passFlag); + if (passFlag == false) { + return Result.failed(ResultCode.ACCESS_UNAUTHORIZED); + } + + // 执行正常业务逻辑 + Object result = joinPoint.proceed(); + return result; + } + +} diff --git a/youlai-common/common-web/src/main/java/com/youlai/common/web/security/annotation/RequirePerms.java b/youlai-common/common-web/src/main/java/com/youlai/common/web/security/annotation/RequirePerms.java new file mode 100644 index 000000000..c89af18d3 --- /dev/null +++ b/youlai-common/common-web/src/main/java/com/youlai/common/web/security/annotation/RequirePerms.java @@ -0,0 +1,19 @@ +package com.youlai.common.web.security.annotation; + +import java.lang.annotation.*; + +/** + * 权限校验注解 + * + * @author haoxr + * @Date 2022/7/30 + */ +@Documented +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface RequirePerms { + + String[] value() default {}; + +} + diff --git a/youlai-common/common-web/src/main/resources/META-INF/spring.factories b/youlai-common/common-web/src/main/resources/META-INF/spring.factories index 5b5dcb2b2..a1e54f95f 100644 --- a/youlai-common/common-web/src/main/resources/META-INF/spring.factories +++ b/youlai-common/common-web/src/main/resources/META-INF/spring.factories @@ -1,4 +1,5 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.youlai.common.web.config.WebMvcConfig,\ com.youlai.common.web.config.FeignConfig,\ - com.youlai.common.web.exception.GlobalExceptionHandler + com.youlai.common.web.exception.GlobalExceptionHandler,\ + com.youlai.common.web.security.advice.PermissionAdvice