SpringAOP实现权限管理
1. 创建Aspect类
/**
* @author flame
*/
@Aspect
@Component
public class AuthorityAspect {
private static final String TOKEN_PREFIX = "Bearer ";
@Autowired
private RsaKeyProperties rsaKeyProperties;
/**
* 定义controller切入点拦截挂载,拦截Authority注解的方法
*/
@Pointcut("@annotation(com.innocent.sams.api.Authority)")
public void authorityAspect() {
}
@Around("authorityAspect()")
public Result checkAuthority(ProceedingJoinPoint joinPoint) throws Throwable {
//获取request对象
HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
String header = request.getHeader("Authorization");
if (StringUtils.isEmpty(header) || !header.startsWith(TOKEN_PREFIX)) {
throw new SamsException(false, StatusCode.USER_NOT_LOGIN);
}
String token = header.replace(TOKEN_PREFIX, "");
//获取token中的用户信息
Payload<UserVO> playLoad = JwtUtils.genInfoFromToken(token, rsaKeyProperties.getPublicKey(), UserVO.class);
if (playLoad == null) {
throw new SamsException(false, StatusCode.USER_NOT_LOGIN);
}
UserVO userVO = playLoad.getUserInfo();
if (userVO == null) {
throw new SamsException(false, StatusCode.USER_NOT_LOGIN);
}
//将当前用户信息放到线程域中
UserContext.set(userVO);
//获取连接点目标类型
String targetName = joinPoint.getTarget().getClass().getName();
//根据连接点类名获取指定类
Class<?> targetClass = Class.forName(targetName);
//获取连接点签名的方法名
String methodName = joinPoint.getSignature().getName();
Method[] methodList = targetClass.getMethods();
for (Method method : methodList) {
if (method.getName().equals(methodName)) {
//获取访问该方法所需的角色信息
List<String> neededRoleList = Arrays.stream(method.getAnnotation(Authority.class).hasAnyRoles().split(",")).collect(Collectors.toList());
List<String> roleNames = userVO.getRoleName();
if (CollectionUtils.isEmpty(roleNames)) {
throw new SamsException(false, StatusCode.NO_PERMISSION);
}
boolean flag = false;
for (int i = 0; i < roleNames.size(); i++) {
if (neededRoleList.contains(roleNames.get(i))) {
flag = true;
break;
} else if (!neededRoleList.contains(roleNames.get(i)) && i == roleNames.size() - 1) {
throw new SamsException(false, StatusCode.NO_PERMISSION);
}
}
if (flag) {
break;
}
}
}
Object proceed = joinPoint.proceed();
return (Result) proceed;
}
}
2. 创建自定义注解
/**
* @author flame
*/
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Authority {
String hasAnyRoles() default "";
}
3.在需要权限的Controller类上加注解即可使用