cn.acyou.leo.framework.aspect.PermissionsAspect Maven / Gradle / Ivy
package cn.acyou.leo.framework.aspect;
import cn.acyou.leo.framework.annotation.authz.Logical;
import cn.acyou.leo.framework.annotation.authz.RequiresLogin;
import cn.acyou.leo.framework.annotation.authz.RequiresPermissions;
import cn.acyou.leo.framework.annotation.authz.RequiresRoles;
import cn.acyou.leo.framework.base.LoginUser;
import cn.acyou.leo.framework.constant.CommonErrorEnum;
import cn.acyou.leo.framework.context.AppContext;
import cn.acyou.leo.framework.exception.ServiceException;
import com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.PatternMatchUtils;
import org.springframework.util.StringUtils;
import java.util.Collection;
import java.util.Set;
/**
*
* 权限校验切面
*
* use support {@link RequiresLogin} & {@link RequiresRoles} & {@link RequiresPermissions}
*
* @author fangyou
* @version [1.0.0, 2021-09-27 15:28]
*/
@Slf4j
@Aspect
@Component
public class PermissionsAspect {
/** 所有权限标识 */
private static final String ALL_PERMISSION = "*:*:*";
@Around("@annotation(cn.acyou.leo.framework.annotation.authz.RequiresLogin) || @annotation(cn.acyou.leo.framework.annotation.authz.RequiresRoles) || @annotation(cn.acyou.leo.framework.annotation.authz.RequiresPermissions)")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
RequiresLogin requiresLogin = methodSignature.getMethod().getAnnotation(RequiresLogin.class);
RequiresRoles requiresRoles = methodSignature.getMethod().getAnnotation(RequiresRoles.class);
RequiresPermissions requiresPermissions = methodSignature.getMethod().getAnnotation(RequiresPermissions.class);
//登录
if (requiresLogin != null) {
LoginUser loginUser = AppContext.getLoginUser();
if (loginUser == null) {
throw new ServiceException(CommonErrorEnum.E_UNAUTHENTICATED);
}
}
//角色
if (requiresRoles != null) {
LoginUser loginUser = AppContext.getLoginUser();
if (loginUser == null) {
throw new ServiceException(CommonErrorEnum.E_UNAUTHENTICATED);
}
Set roleCodes = loginUser.getRoleCodes();
Logical logical = requiresRoles.logical();
String[] needRoles = requiresRoles.value();
if (logical.equals(Logical.AND)) {
boolean containsAll = roleCodes.containsAll(Sets.newHashSet(needRoles));
if (!containsAll) {
throw new ServiceException(CommonErrorEnum.E_INSUFFICIENT_PERMISSIONS);
}
}
if (logical.equals(Logical.OR)) {
boolean containsAny = CollectionUtils.containsAny(roleCodes, Sets.newHashSet(needRoles));
if (!containsAny) {
throw new ServiceException(CommonErrorEnum.E_INSUFFICIENT_PERMISSIONS);
}
}
}
//权限
if (requiresPermissions != null) {
LoginUser loginUser = AppContext.getLoginUser();
if (loginUser == null) {
throw new ServiceException(CommonErrorEnum.E_UNAUTHENTICATED);
}
Set permsList = loginUser.getPermsList();
Logical logical = requiresPermissions.logical();
String[] needPermissions = requiresPermissions.value();
if (logical.equals(Logical.AND)) {
boolean containsAll = checkPermsAnd(permsList, needPermissions);
if (!containsAll) {
throw new ServiceException(CommonErrorEnum.E_INSUFFICIENT_PERMISSIONS);
}
}
if (logical.equals(Logical.OR)) {
boolean containsAny = checkPermsOr(permsList, needPermissions);
if (!containsAny) {
throw new ServiceException(CommonErrorEnum.E_INSUFFICIENT_PERMISSIONS);
}
}
}
return joinPoint.proceed();
}
/**
* 验证用户是否含有指定权限,必须全部拥有
*
* @param permissions 权限列表
*/
public boolean checkPermsAnd(Set permissionList, String... permissions) {
for (String permission : permissions) {
if (!hasPermi(permissionList, permission)) {
return false;
}
}
return true;
}
/**
* 验证用户是否含有指定权限,只需包含其中一个
*
* @param permissions 权限码数组
*/
public boolean checkPermsOr(Set permissionList, String... permissions) {
for (String permission : permissions) {
if (hasPermi(permissionList, permission)) {
return true;
}
}
return permissions.length <= 0;
}
/**
* 判断是否包含权限
*
* @param authorities 权限列表
* @param permission 权限字符串
* @return 用户是否具备某权限
*/
public boolean hasPermi(Collection authorities, String permission) {
return authorities.stream().filter(StringUtils::hasText)
.anyMatch(x -> ALL_PERMISSION.contains(x) || PatternMatchUtils.simpleMatch(x, permission));
}
}