![JAR search and dependency download from the Maven repository](/logo.png)
ink.huaxun.authority.aspect.RequiresPermissionsAspect Maven / Gradle / Ivy
package ink.huaxun.authority.aspect;
import ink.huaxun.authority.annotation.RequiresPermissions;
import ink.huaxun.redis.util.RedisUtil;
import ink.huaxun.util.HttpServletUtil;
import ink.huaxun.util.JwtUtil;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.AuthorizationException;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
/**
* @author zhaogang
* @description 权限切面
* @date 2023/2/7 17:48
*/
@Aspect
@Component
public class RequiresPermissionsAspect {
/**
* token的头
*/
@Value("${token.header}")
private String header;
/**
* redis的用户权限key
*/
@Value("${redis.permission-user-id}")
private String permissionUserIdKey;
/**
* uri前缀
*/
private static final String URI_PREFIX = "/";
/**
* uri后缀
*/
private static final String URI_SUFFIX = "/";
/**
* uri分隔符
*/
private static final String URI_SEPARATOR = "/";
/**
* 权限分隔符
*/
private static final String PERMISSION_SEPARATOR = ":";
/**
* PathVariable的前缀
*/
private static final String PATH_VARIABLE_PREFIX = "{";
/**
* 编辑权限
*/
private static final String EDIT = "edit";
/**
* 查看权限
*/
private static final String GET = "get";
/**
* 切面操作
*/
@Around("@annotation(ink.huaxun.authority.annotation.RequiresPermissions)")
public Object around(ProceedingJoinPoint point) throws Throwable {
Signature signature = point.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Method method = methodSignature.getMethod();
RequiresPermissions annotation = method.getAnnotation(RequiresPermissions.class);
if (annotation == null) {
return point.proceed();
}
HttpServletRequest request = HttpServletUtil.getRequest();
if (request == null) {
throw new AuthorizationException("request is null!");
}
// 尝试在这里获得请求url
String[] authority = annotation.value();
if (ArrayUtils.isEmpty(authority)) {
String uri = request.getRequestURI();
authority = this.uriToPermission(uri, method);
}
String token = request.getHeader(header);
if (!this.has(authority, token)) {
throw new AuthorizationException("无操作权限");
}
return point.proceed();
}
/**
* 判断登录用户是否有权限
*/
private boolean has(String[] authority, String token) {
String userId = JwtUtil.getId(token);
String key = permissionUserIdKey + userId;
for (String permission : authority) {
Boolean value = RedisUtil.hasHashItem(key, permission);
if (BooleanUtils.isTrue(value)) {
return true;
}
}
return false;
}
/**
* uri转权限
*/
private String[] uriToPermission(String uri, Method method) {
if (StringUtils.isBlank(uri)) {
return ArrayUtils.EMPTY_STRING_ARRAY;
}
String value = this.getMappingValue(method);
uri = this.removePathVariable(value, uri, method.getName());
uri = uri.replaceFirst(URI_PREFIX, StringUtils.EMPTY);
String permission = uri.replaceAll(URI_SEPARATOR, PERMISSION_SEPARATOR);
String[] subsidiary = this.getSubsidiaryPermission(permission);
return ArrayUtils.addAll(subsidiary, permission);
}
/**
* 获取注解中的value值
*/
private String getMappingValue(Method method) {
String[] value = this.getMappingValues(method);
if (ArrayUtils.isEmpty(value)) {
return StringUtils.EMPTY;
}
return value[0];
}
/**
* 获取注解中的value数组
*/
private String[] getMappingValues(Method method) {
GetMapping getMapping = method.getAnnotation(GetMapping.class);
if (getMapping != null) {
return getMapping.value();
}
PostMapping postMapping = method.getAnnotation(PostMapping.class);
if (postMapping != null) {
return postMapping.value();
}
PutMapping putMapping = method.getAnnotation(PutMapping.class);
if (putMapping != null) {
return putMapping.value();
}
DeleteMapping deleteMapping = method.getAnnotation(DeleteMapping.class);
if (deleteMapping != null) {
return deleteMapping.value();
}
RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
if (requestMapping != null) {
return requestMapping.value();
}
return ArrayUtils.EMPTY_STRING_ARRAY;
}
/**
* 删除PathVariable参数,补充方法名作为权限值
*/
private String removePathVariable(String value, String uri, String methodName) {
// 排除路由为"/"的影响
value = value.replaceFirst(URI_PREFIX, StringUtils.EMPTY);
// 排除路由以"/"结尾的影响
if (uri.endsWith(URI_SUFFIX)) {
uri = uri.substring(0, uri.lastIndexOf(URI_SUFFIX));
}
// 当路由为空或仅有PathVariable情况下,需要补充方法名作为权限值
if (StringUtils.isBlank(value)) {
return uri + URI_SEPARATOR + methodName;
}
// 正常路由情况下,直接使用uri
if (!value.contains(PATH_VARIABLE_PREFIX)) {
return uri;
}
// PathVariable的情况下,需要去除PathVariable部分的uri(最后一段/{xxx})
int start = 0;
while ((start = value.indexOf(PATH_VARIABLE_PREFIX, start)) >= 0) {
start += PATH_VARIABLE_PREFIX.length();
uri = uri.substring(0, uri.lastIndexOf(URI_SEPARATOR));
}
// uri最后一段相同时,默认合并(不允许uri出现连续相同字符串)
if (uri.endsWith(URI_SEPARATOR + methodName)) {
return uri;
}
return uri + URI_SEPARATOR + methodName;
}
/**
* 获取额外的附属权限
*/
private String[] getSubsidiaryPermission(String permission) {
// 请求查看方法时,如果有编辑权限,则视为通过
if (permission.endsWith(PERMISSION_SEPARATOR + GET)) {
String subsidiary = permission.substring(0, permission.lastIndexOf(GET)) + EDIT;
return new String[]{subsidiary};
}
return null;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy