完成了新的鉴权切面
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 张韬
|
* @author 张韬
|
||||||
* created at 2022/6/28 21:24
|
* 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 WRONG_PARAMETERS = "参数错误";
|
||||||
public static final String OPERATE_FAILED = "操作失败";
|
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 佘语殊
|
* @author 佘语殊
|
||||||
* @since 2022/7/6 20:14
|
* @since 2022/7/6 20:14
|
||||||
*/
|
*/
|
||||||
public class ForbiddenException extends Exception {
|
public class ForbiddenException extends BusinessException {
|
||||||
|
|
||||||
public static final String UNABLE_TO_OPERATE = "无该操作权限";
|
public static final String UNABLE_TO_OPERATE = "无该操作权限";
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ package cn.edu.hfut.rmdjzz.projectmanagement.exception;
|
||||||
* @author 佘语殊
|
* @author 佘语殊
|
||||||
* @since 2022/7/11 17:35
|
* @since 2022/7/11 17:35
|
||||||
*/
|
*/
|
||||||
public class TooManyRequestException extends Exception {
|
public class TooManyRequestException extends BusinessException {
|
||||||
public TooManyRequestException(String message) {
|
public TooManyRequestException(String message) {
|
||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ package cn.edu.hfut.rmdjzz.projectmanagement.exception;
|
||||||
* @author 佘语殊
|
* @author 佘语殊
|
||||||
* @since 2022/7/5 23:36
|
* @since 2022/7/5 23:36
|
||||||
*/
|
*/
|
||||||
public class UnauthorizedException extends Exception {
|
public class UnauthorizedException extends BusinessException {
|
||||||
public UnauthorizedException(String message) {
|
public UnauthorizedException(String message) {
|
||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,8 +36,6 @@ public class TokenInterceptor implements HandlerInterceptor {
|
||||||
if (TokenUtils.checkTimeOut(token)) {
|
if (TokenUtils.checkTimeOut(token)) {
|
||||||
throw new TokenException("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))))) {
|
if (!token.equals(redisTemplate.opsForValue().get(Objects.<Integer>requireNonNull(TokenUtils.getStaffId(token))))) {
|
||||||
throw new TokenException("请重新登录");
|
throw new TokenException("请重新登录");
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,9 @@ public final class TokenUtils {
|
||||||
public final static String HEADER_TOKEN = "Token";
|
public final static String HEADER_TOKEN = "Token";
|
||||||
public final static String STAFF_USERNAME = "staffUsername";
|
public final static String STAFF_USERNAME = "staffUsername";
|
||||||
public final static String STAFF_ID = "staffId";
|
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";
|
private final static String DURATION = "duration";
|
||||||
|
|
||||||
public static String getToken(String staffUsername, Integer staffId, Integer staffGlobalLevel, Long 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;
|
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 javax.servlet.http.HttpServletRequest;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
|
@ -52,4 +55,13 @@ public class HttpUtils {
|
||||||
private static boolean ipAddressAvailable(String ipAddress) {
|
private static boolean ipAddressAvailable(String ipAddress) {
|
||||||
return ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(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 cn.edu.hfut.rmdjzz.projectmanagement.utils.TimeUtils;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import org.junit.jupiter.api.Test;
|
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.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
@ -29,4 +31,14 @@ public class UtilTests {
|
||||||
Class<?> returnType = this.getClass().getMethod("timeTest").getReturnType();
|
Class<?> returnType = this.getClass().getMethod("timeTest").getReturnType();
|
||||||
System.out.println(returnType.equals(void.class));
|
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