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 {@Resourceprivate TokenDTO tokenDTO;@Resourceprivate StringRedisTemplate stringRedisTemplate;@Resourceprivate 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’)”)
有需要可以去看看,这里就不多说了