Springboot通过注解+切面实现接口权限校验

Springboot通过注解+切面实现接口权限校验


主要说一下在对接口请求时,如何用注解+切面去拦截校验当前登录用户是否有访问权限

在这里插入图片描述

1.首先创建注解 @HasPermission ,跟普通注解创建方式基本一致

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface HasPermission {
    String permission() default "";
}

2.创建一个切面,用来请求接口时做前置校验
主要思路:
先获取到注解@HasPermission 的内容,从redis中拿到当前用户角色的所有权限,如果当前用户不是超级管理员并且权限中不包含要请求的接口权限,就返回未授权。
用户在登录时会查询数据库将角色的所有权限存入redis,如果对角色做权限修改时,同步修改redis,这样每次请求接口时,都能从redis中拿到最新的权限。

@Aspect
@Component
public class PermissionAspect {

    @Resource
    private TokenDTO tokenDTO;
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private RoleRepository roleRepository;


    /**
     * 前置通知
     * @param joinPoint
     */
    @Before("pointCut()")
    public void checkPermission(JoinPoint joinPoint) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        HasPermission annotation = method.getAnnotation(HasPermission.class);
        if (annotation != null) {
            String permission = annotation.permission();
            roleRepository.findById(tokenDTO.getRoleId()).ifPresent(roleDO -> {
            	//从redis中取出当前角色的所有权限
            	String permissions = stringRedisTemplate.opsForValue().get(roleDO.getId());
                if (!roleDO.getCode().equals(UserConstant.ROLE_SUPER_ADMIN) && permissions != null) {
                    if (!permissions.contains(permission)) {
                        throw new UnauthorizedException("unauthorized");
                    }
                }
            });
        }
    }

    /**
     * 切点
     */
    @Pointcut("@annotation(com.******************.annotation.HasPermission)")
    public void pointCut() {

    }
}

3.接口上方加上注解 @HasPermission(permission = “country:list”),这样每次请求接口时有提前校验,“country:list” 要和数据库中保存的权限内容保持一致,这样才能做判断

@HasPermission(permission = "country:list")
@GetMapping("/countries/list")
public Result filterCountry(CountryFilterDTO countryFilterDto, CustomPageable pageable) {
        return countryService.filterCountry(countryFilterDto, pageable);
}

另外,还有一种权限校验的方式,可以参考若依的开源,类似这种
@PreAuthorize(“@ss.hasPermi(‘system:role:edit’)”)
有需要可以去看看,这里就不多说了

上一篇:Mac 配置环境变量和处理路径中空格


下一篇:Java全栈课程之Linux———入门概述