AOP 在 Spring Boot 中的应用

  • 自定义权限注解
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    package com.yzyx.repomanage.aop;

    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Permission {
    /**
    * 权限值
    * @return
    */
    String value() default "";
    }

  • 获取注解参数值
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    package com.yzyx.repomanage.aop;

    public class ParsePermission {
    public static String parse(Class targetClass, String methodName, JoinPoint joinPoint) throws Exception {
    // 获取方法
    MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
    Method method = methodSignature.getMethod();
    String value = "";
    // 如果方法带了注解
    if (method.isAnnotationPresent(Permission.class)) {
    Permission permission = method.getAnnotation(Permission.class);
    value = permission.value();
    }
    return value;
    }
    }

  • AOP 切面权限控制
    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
    package com.yzyx.repomanage.aop;

    @Aspect
    @Component
    @Slf4j
    public class PermissionAspect {
    @Resource
    RoleUserService roleUserService;
    @Resource
    RoleAuthorityService roleAuthorityService;
    @Resource
    AuthorityService authorityService;

    @Pointcut("execution(public * com.yzyx.repomanage.controller.*.*(..))")
    public void aspectTarget(){
    log.info("进行权限验证");
    }

    @Around("aspectTarget()")
    public Object executeAround(ProceedingJoinPoint joinPoint) throws Throwable {
    // 获取请求信息
    ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    HttpServletRequest request = requestAttributes.getRequest();
    HttpServletResponse response = requestAttributes.getResponse();
    // 如果具有权限,继续执行方法
    Object object = null;
    if (hasPermission(joinPoint, request)) {
    object = joinPoint.proceed();
    } else {
    response.setHeader("Content-type","application/json; charset=UTF-8");
    OutputStream outputStream = response.getOutputStream();
    Result result = Result.UserError().appendInfo("权限不足");
    outputStream.write(new ObjectMapper().writeValueAsString(result).getBytes("UTF-8"));
    }
    return object;
    }

    private boolean hasPermission(JoinPoint joinPoint, HttpServletRequest request) throws Exception {
    Class targetClass = joinPoint.getTarget().getClass();
    String methodName = joinPoint.getSignature().getName();
    // 获取执行方法的权限
    String value = ParsePermission.parse(targetClass, methodName, joinPoint);
    log.info("[Required permission] {}", value);
    if (value.equals("")) {
    return true;
    }
    // 从请求头中获取token
    String token = request.getHeader(JwtTokenUtil.AUTH_HEADER_KEY);
    if (token != null) {
    log.info(token);
    Claims claims = null;
    try {
    claims = JwtTokenUtil.parseJWT(token);
    } catch (UserException e) {
    log.error(e.getMessage());
    e.printStackTrace();
    }
    // 判断该用户是否具有权限
    String username = claims.getSubject();
    return checkDatabase(value, username);
    }
    return false;
    }

    private boolean checkDatabase(String value, String username) {
    boolean checked = false;
    // 获取用户具有的角色
    List<RoleUser> roleUserList = roleUserService.getRoleUsers(username);
    // 获取角色具有的权限
    List<RoleAuthority> roleAuthorityList = roleAuthorityService.getRoleAuthorities(roleUserList);
    // 获取权限名称
    List<Authority> authorityList = authorityService.getAuthorities(roleAuthorityList);
    for(Authority authority : authorityList) {
    if (authority.getName().equals(value)) {
    checked = true;
    break;
    }
    }
    return checked;
    }

    @AfterReturning(returning = "response", pointcut = "aspectTarget()")
    public void doAfterReturning(Object response){
    log.info("[Response] " + response);
    }

    }