Spring AOP校验权限

权限校验是一个比较通用的业务需求,一般会通过 Spring AOP 切面 + 自定义权限校验注解 实现统一的接口拦截和权限校验;

常用的认证框架有

框架/工具

适用场景

主要特点

优点

缺点

Spring Security

复杂的企业级应用

强大的安全功能,与 Spring 集成良好

功能全面,安全性强,社区支持广泛

学习曲线陡峭,配置繁琐

Apache Shiro

中小型项目

轻量级,易于使用

简单易用,灵活,适合快速上手

功能相对有限,文档不够完善

Auth0

云端身份管理需求

托管服务,功能丰富

易于使用,功能强大,适合云端解决方案

费用高昂,依赖外部服务

Sa-Token

快速开发的中小型项目

轻量级、易用性强,专注于认证和授权

轻量级,启动快API 简洁,易于上手灵活性高

社区相对较小生态不如 Spring Security 完善

Sa-Token以前的文章有使用,需要的可参考Sa-Token常用方法以及整合_satoken-优快云博客

使用aop注解进行权限校验

1.先创建一个AuthCheck注解用于权限校验

@Target(ElementType.METHOD) //只在方法上生效
@Retention(RetentionPolicy.RUNTIME) //运行时生效
public @interface AuthCheck {
    /**
     * 必须有某个角色
     */
    String mustRole() default "";
}

2.创建一个java类进行设置切入点和要操作的内容

@Aspect
@Component
public class AuthInterceptor {

    //基于 AOP(面向切面编程)的权限校验逻辑,使用了 Spring 的 @Around 切面方法来拦截带有 @AuthCheck 注解的方法调用,
    // 并根据注解中的 mustRole 属性进行权限验证

    @Resource
    private UserService userService;

    /**
     * 执行拦截
     *
     * @param joinPoint 切入点
     * @param authCheck 权限校验注解
     */
    //会拦截所有带有 @AuthCheck 注解的目标方法。
    //authCheck 是 @AuthCheck 注解的参数化引用,用于获取注解实例。
    @Around("@annotation(authCheck)")
    public Object doInterceptor(ProceedingJoinPoint joinPoint, AuthCheck authCheck) throws Throwable {
        //ProceedingJoinPoint joinPoint:这是 Spring AOP 提供的一个接口,
        // 代表被拦截的目标方法的连接点。通过它可以调用目标方法(joinPoint.proceed())
        //AuthCheck authCheck:这是从注解中提取的 @AuthCheck 实例,用于访问注解的属性值(如 mustRole)。

        String mustRole = authCheck.mustRole(); //获取mustRole属性的值

        //使用 RequestContextHolder 获取当前线程绑定的请求上下文。
        //将其转换为 ServletRequestAttributes 并提取出 HttpServletRequest 对象,用于后续获取登录用户信息。
        RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
        HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();

        // 当前登录用户
        User loginUser = userService.getLoginUser(request);
        UserEnumRole mustRoleEnum = UserEnumRole.getEnumRoleByValue(mustRole);
        // 不需要权限,放行
        if (mustRoleEnum == null) {
            return joinPoint.proceed();
        }
        // 以下为:必须有该权限才通过
        // 获取当前用户具有的权限
        UserEnumRole userRoleEnum = UserEnumRole.getEnumRoleByValue(loginUser.getUserRole());
    
        if (userRoleEnum == null) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
        }
        //检查目标方法是否要求管理员权限(mustRoleEnum 是否为 ADMIN)。如果是,且当前用户不是管理员,则抛出业务异常,拒绝访问。
        if (UserEnumRole.ADMIN.equals(mustRoleEnum) && !UserEnumRole.ADMIN.equals(userRoleEnum)) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
        }
        // 通过权限校验,放行
        return joinPoint.proceed();
    }

}

使用也比较简单,只需要在需要校验的方法上加上自定义注解即可

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值