使用自定义注解实现角色权限

注解类

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface AuthCheckRole {

    /**
     * 需要校验的角色标识 [ 数组 ]
     *
     * @return /
     */
    String[] value() default {};

    /**
     * 验证模式:AND | OR,默认AND
     *
     * @return /
     */
    ValidationMode mode() default ValidationMode.AND;

}

切面类

@Slf4j
@Aspect
public class AuthRoleAspect {

    /**
     * 执行拦截
     *
     * @param joinPoint
     * @param authCheckRole
     * @return
     */
    @Around("@annotation(authCheckRole)")
    public Object doInterceptor(ProceedingJoinPoint joinPoint, AuthCheckRole authCheckRole) throws Throwable {

        RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
        HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
        String token = request.getHeader(RequestHeaderName.TOKEN);
        RedisService redisService = SpringUtil.getBean(RedisService.class);
        // 获取当前用户的信息
        LoginToken loginToken = redisService.getCacheObject(TokenConstants.REDIS_KEY_PREFIX + token);
        //回调的时候会是NULL
        if (loginToken == null) {
            throw new ServiceException("未登录");
        }
        //管理员看全部
//        if (loginToken.getSuperManager() == 1) {
//            // 通过权限校验,放行
//            return joinPoint.proceed();
//        }

        //临时
        HashSet<String> strings = new HashSet<>();
        strings.add(RoleConstants.TENANT_ADMIN_ROLE_KEY);
        loginToken.setRoleList(strings);

        Set<String> roleList = loginToken.getRoleList();
        if (CollUtil.isEmpty(roleList)) {
            throw new ServiceException("角色权限不存在");
        }
        String[] roleArray = authCheckRole.value();
        if (authCheckRole.mode() == ValidationMode.AND) {
            this.checkRoleAnd(roleArray, roleList);
        } else {
            this.checkRoleOr(roleArray, roleList);
        }
        // 通过权限校验,放行
        return joinPoint.proceed();
    }

    /**
     * 校验:当前账号是否含有指定角色标识 [ 指定多个,必须全部验证通过 ]
     *
     * @param roleArray 角色标识数组
     */
    public void checkRoleAnd(String[] roleArray, Set<String> roleList) {
        // 如果没有指定要校验的角色,那么直接跳过
        if (roleArray == null || roleArray.length == 0) {
            return;
        }
        // 开始校验
        for (String role : roleArray) {
            if (!roleList.contains(role)) {
                throw new ServiceException("角色权限不足,请联系管理员");
            }
        }
    }

    /**
     * 校验:当前账号是否含有指定角色标识 [ 指定多个,只要其一验证通过即可 ]
     *
     * @param roleArray 角色标识数组
     */
    public void checkRoleOr(String[] roleArray, Set<String> roleList) {
        // 如果没有指定权限,那么直接跳过
        if (roleArray == null || roleArray.length == 0) {
            return;
        }
        // 开始校验
        for (String role : roleArray) {
            if (roleList.contains(role)) {
                // 有的话提前退出
                return;
            }
        }
        // 代码至此,说明一个都没通过,需要抛出无角色异常
        throw new ServiceException("角色异常");
    }
}

配置类 

@Configuration
public class AuthRoleConfig {
    @Bean
    public AuthRoleAspect authRoleAspect() {
        return new AuthRoleAspect();
    }

}

 固定角色配置

public interface RoleConstants {

    /**
     * 超级管理员ID
     */
    String SUPER_ADMIN_ID = "1";

    /**
     * 超级管理员角色 roleKey
     */
    String SUPER_ADMIN_ROLE_KEY = "superadmin";

    /**
     * 租户管理员角色 roleKey
     */
    String TENANT_ADMIN_ROLE_KEY = "admin";

    /**
     * 租户管理员角色名称
     */
    String TENANT_ADMIN_ROLE_NAME = "管理员";

}

枚举

public enum ValidationMode {

    /**
     * 必须具有所有的元素
     */
    AND,

    /**
     * 只需具有其中一个元素
     */
    OR

}

注解的使用

 @AuthCheckRole(value = {
            RoleConstants.SUPER_ADMIN_ROLE_KEY,
            RoleConstants.TENANT_ADMIN_ROLE_KEY
    }, mode = ValidationMode.OR)

  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
自定义注解可以用于实现AOP鉴权,以下是一个简单的示例代码,展示了如何使用自定义注解实现AOP鉴权。 首先,定义一个自定义注解 `@Authorization`: ```java import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface Authorization { String[] roles() default {}; } ``` 然后,在需要进行鉴权的方法上添加 `@Authorization` 注解,并指定允许访问的角色列表: ```java public class MyService { @Authorization(roles = {"admin", "superuser"}) public void performAuthorizedAction() { // 执行需要鉴权的操作 } public void performUnauthenticatedAction() { // 执行无需鉴权的操作 } } ``` 接下来,创建一个切面类 `AuthorizationAspect`,在该类中使用 `@Around` 注解来拦截被 `@Authorization` 注解修饰的方法,并进行鉴权验证: ```java import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.stereotype.Component; @Component @Aspect public class AuthorizationAspect { @Around("@annotation(authorization)") public Object authorize(ProceedingJoinPoint joinPoint, Authorization authorization) throws Throwable { // 模拟鉴权逻辑 if (isUserAuthorized(authorization.roles())) { return joinPoint.proceed(); // 继续执行被拦截方法 } else { throw new UnauthorizedAccessException("Access denied"); // 抛出异常或执行其他处理 } } private boolean isUserAuthorized(String[] roles) { // 实际的鉴权逻辑,比如根据用户角色判断是否有权限访问 // 返回 true 表示有权限,返回 false 表示无权限 return true; } } ``` 最后,使用 Spring 或其他 AOP 框架来启用该切面,确保切面类被正确加载和生效。 通过以上步骤,你可以实现自定义注解用于AOP鉴权,对指定的方法进行权限验证。当调用被 `@Authorization` 注解修饰的方法时,会触发切面逻辑,在切面中进行鉴权验证,根据验证结果决定是否允许继续执行方法。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值