完成了新的鉴权切面
parent
dd681a9f20
commit
75d07779c1
|
@ -0,0 +1,71 @@
|
|||
package cn.edu.hfut.rmdjzz.projectmanagement.aop;
|
||||
|
||||
import cn.edu.hfut.rmdjzz.projectmanagement.annotation.ProjectAuthorize;
|
||||
import cn.edu.hfut.rmdjzz.projectmanagement.exception.ForbiddenException;
|
||||
import cn.edu.hfut.rmdjzz.projectmanagement.service.IProjectGroupService;
|
||||
import cn.edu.hfut.rmdjzz.projectmanagement.service.IProjectService;
|
||||
import cn.edu.hfut.rmdjzz.projectmanagement.utils.TokenUtils;
|
||||
import cn.edu.hfut.rmdjzz.projectmanagement.utils.http.HttpUtils;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Before;
|
||||
import org.aspectj.lang.annotation.Pointcut;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.expression.ExpressionParser;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.context.request.RequestAttributes;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Aspect
|
||||
@Component
|
||||
public class ProjectAuthorizeAOP {
|
||||
|
||||
@Autowired
|
||||
private IProjectService projectService;
|
||||
@Autowired
|
||||
private IProjectGroupService projectGroupService;
|
||||
|
||||
@Pointcut("@annotation(cn.edu.hfut.rmdjzz.projectmanagement.annotation.ProjectAuthorize)")
|
||||
public void pointcut() {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Before(value = "pointcut()")
|
||||
public void preAuthorize(JoinPoint joinPoint) throws ForbiddenException {
|
||||
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||
assert attributes != null;
|
||||
MethodSignature signature = (MethodSignature) (joinPoint.getSignature());
|
||||
ProjectAuthorize annotation = signature.getMethod().getAnnotation(ProjectAuthorize.class);
|
||||
String expression = annotation.value();
|
||||
|
||||
Integer globalAccessLevel = HttpUtils.getAttribute(attributes, TokenUtils.STAFF_GLOBAL_LEVEL);
|
||||
Integer projectAccessLevel = null;
|
||||
if (expression.contains("a")) { // 如果涉及到项目权限
|
||||
Integer staffId = HttpUtils.getAttribute(attributes, TokenUtils.STAFF_ID);
|
||||
Map<String, String> pathVariables = ((Map<String, String>) (attributes
|
||||
.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, RequestAttributes.SCOPE_REQUEST)));
|
||||
assert pathVariables != null;
|
||||
Integer projectId = Integer.parseInt(pathVariables.get("projectId"));
|
||||
projectAccessLevel = projectGroupService.getProjectAccessLevel(staffId, globalAccessLevel, projectId);
|
||||
attributes.setAttribute(TokenUtils.PROJECT_ACCESS_LEVEL, projectAccessLevel, RequestAttributes.SCOPE_REQUEST);
|
||||
attributes.setAttribute(TokenUtils.TARGET_PROJECT, projectService.getById(projectId), RequestAttributes.SCOPE_REQUEST);
|
||||
}
|
||||
// 解析SpEL表达式
|
||||
ExpressionParser parser = new SpelExpressionParser();
|
||||
Boolean result = parser.parseExpression(expression)
|
||||
.getValue(new ValidateObject(globalAccessLevel, projectAccessLevel), Boolean.class);
|
||||
if (!Boolean.TRUE.equals(result)) {
|
||||
throw new ForbiddenException(ForbiddenException.UNABLE_TO_OPERATE);
|
||||
}
|
||||
}
|
||||
|
||||
private record ValidateObject(Integer g, Integer a) {
|
||||
|
||||
}
|
||||
}
|
|
@ -4,7 +4,7 @@ package cn.edu.hfut.rmdjzz.projectmanagement.exception;
|
|||
* @author 张韬
|
||||
* created at 2022/6/28 21:24
|
||||
*/
|
||||
public class BadRequestException extends Exception {
|
||||
public class BadRequestException extends BusinessException {
|
||||
|
||||
public static final String WRONG_PARAMETERS = "参数错误";
|
||||
public static final String OPERATE_FAILED = "操作失败";
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
package cn.edu.hfut.rmdjzz.projectmanagement.exception;
|
||||
|
||||
public class BusinessException extends RuntimeException {
|
||||
public BusinessException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Throwable fillInStackTrace() {
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -4,7 +4,7 @@ package cn.edu.hfut.rmdjzz.projectmanagement.exception;
|
|||
* @author 佘语殊
|
||||
* @since 2022/7/6 20:14
|
||||
*/
|
||||
public class ForbiddenException extends Exception {
|
||||
public class ForbiddenException extends BusinessException {
|
||||
|
||||
public static final String UNABLE_TO_OPERATE = "无该操作权限";
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ package cn.edu.hfut.rmdjzz.projectmanagement.exception;
|
|||
* @author 佘语殊
|
||||
* @since 2022/7/11 17:35
|
||||
*/
|
||||
public class TooManyRequestException extends Exception {
|
||||
public class TooManyRequestException extends BusinessException {
|
||||
public TooManyRequestException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ package cn.edu.hfut.rmdjzz.projectmanagement.exception;
|
|||
* @author 佘语殊
|
||||
* @since 2022/7/5 23:36
|
||||
*/
|
||||
public class UnauthorizedException extends Exception {
|
||||
public class UnauthorizedException extends BusinessException {
|
||||
public UnauthorizedException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
|
|
@ -36,8 +36,6 @@ public class TokenInterceptor implements HandlerInterceptor {
|
|||
if (TokenUtils.checkTimeOut(token)) {
|
||||
throw new TokenException("Token已过期");
|
||||
}
|
||||
// log.debug(Objects.requireNonNull(TokenUtils.getStaffId(token)));
|
||||
// log.debug(token);
|
||||
if (!token.equals(redisTemplate.opsForValue().get(Objects.<Integer>requireNonNull(TokenUtils.getStaffId(token))))) {
|
||||
throw new TokenException("请重新登录");
|
||||
}
|
||||
|
|
|
@ -21,7 +21,9 @@ public final class TokenUtils {
|
|||
public final static String HEADER_TOKEN = "Token";
|
||||
public final static String STAFF_USERNAME = "staffUsername";
|
||||
public final static String STAFF_ID = "staffId";
|
||||
public final static String STAFF_GLOBAL_LEVEL = "staffGlobalLevel";
|
||||
public final static String STAFF_GLOBAL_LEVEL = "globalAccessLevel";
|
||||
public final static String PROJECT_ACCESS_LEVEL = "projectAccessLevel";
|
||||
public static final String TARGET_PROJECT = "targetProject";
|
||||
private final static String DURATION = "duration";
|
||||
|
||||
public static String getToken(String staffUsername, Integer staffId, Integer staffGlobalLevel, Long duration) {
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
package cn.edu.hfut.rmdjzz.projectmanagement.utils.http;
|
||||
|
||||
import org.springframework.web.context.request.RequestAttributes;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
@ -52,4 +55,13 @@ public class HttpUtils {
|
|||
private static boolean ipAddressAvailable(String ipAddress) {
|
||||
return ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T getAttribute(ServletRequestAttributes attributes, String key) {
|
||||
Object value = attributes.getAttribute(key, RequestAttributes.SCOPE_REQUEST);
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return (T) value;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@ package cn.edu.hfut.rmdjzz.projectmanagement;
|
|||
import cn.edu.hfut.rmdjzz.projectmanagement.utils.TimeUtils;
|
||||
import lombok.SneakyThrows;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.expression.ExpressionParser;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
|
@ -29,4 +31,14 @@ public class UtilTests {
|
|||
Class<?> returnType = this.getClass().getMethod("timeTest").getReturnType();
|
||||
System.out.println(returnType.equals(void.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void spelTest() {
|
||||
ExpressionParser parser = new SpelExpressionParser();
|
||||
System.out.println(parser.parseExpression("a == 1").getValue(new R(2), Boolean.class));
|
||||
System.out.println(parser.parseExpression("a == 1").getValue(new R(1), Boolean.class));
|
||||
}
|
||||
|
||||
record R(int a) {
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue