WANG 6 years ago
parent
commit
be955bf43b

+ 2 - 22
src/main/java/cn/com/qmth/examcloud/web/enums/HttpServletRequestAttribute.java

@@ -19,35 +19,15 @@ public enum HttpServletRequestAttribute {
 	 */
 	$_API_INFO,
 
-	/**
-	 * 接入类型
-	 */
-	$_ACCESS_TYPE,
-
 	/**
 	 * http status恒为200
 	 */
 	$_ALWAYS_OK,
 
 	/**
-	 * 接入的管理员用户
-	 */
-	$_ACCESS_ADMIN_USER,
-
-	/**
-	 * 接入的分区用户
-	 */
-	$_ACCESS_PARTITION_USER,
-
-	/**
-	 * 接入的APP
-	 */
-	$_ACCESS_APP,
-
-	/**
-	 * 接入的企业
+	 * 接入用户
 	 */
-	$_ACCESS_ENTERPRISE,
+	$_ACCESS_USER,
 
 	/**
 	 * 自定义顺序锁

+ 29 - 100
src/main/java/cn/com/qmth/examcloud/web/security/RequestPermissionInterceptor.java

@@ -1,32 +1,22 @@
 package cn.com.qmth.examcloud.web.security;
 
-import java.io.File;
-import java.io.IOException;
-import java.util.List;
-import java.util.Set;
-
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import org.apache.commons.collections.CollectionUtils;
-import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang3.StringUtils;
-import org.slf4j.MDC;
+import org.apache.logging.log4j.ThreadContext;
 import org.springframework.http.HttpStatus;
 import org.springframework.web.servlet.HandlerInterceptor;
 import org.springframework.web.servlet.ModelAndView;
 
-import com.google.common.collect.Sets;
-
 import cn.com.qmth.examcloud.api.commons.CloudService;
 import cn.com.qmth.examcloud.api.commons.EnterpriseService;
 import cn.com.qmth.examcloud.api.commons.security.bean.User;
 import cn.com.qmth.examcloud.commons.logging.ExamCloudLog;
 import cn.com.qmth.examcloud.commons.logging.ExamCloudLogFactory;
-import cn.com.qmth.examcloud.commons.util.JsonUtil;
-import cn.com.qmth.examcloud.commons.util.PathUtil;
-import cn.com.qmth.examcloud.commons.util.RegExpUtil;
+import cn.com.qmth.examcloud.web.enums.HttpServletRequestAttribute;
 import cn.com.qmth.examcloud.web.redis.RedisClient;
+import cn.com.qmth.examcloud.web.support.ApiInfo;
 import cn.com.qmth.examcloud.web.support.ServletUtil;
 import cn.com.qmth.examcloud.web.support.StatusResponse;
 
@@ -42,40 +32,13 @@ public abstract class RequestPermissionInterceptor implements HandlerInterceptor
 	private static final ExamCloudLog LOG = ExamCloudLogFactory
 			.getLog(RequestPermissionInterceptor.class);
 
-	/**
-	 * 接口日志
-	 */
 	protected static final ExamCloudLog INTERFACE_LOG = ExamCloudLogFactory
 			.getLog("INTERFACE_LOGGER");
 
-	private static final Set<String> RESOURCE_NAME_SET = Sets.newConcurrentHashSet();
+	private ResourceManager resourceManager;
 
-	/**
-	 * redis client
-	 */
 	private RedisClient redisClient;
 
-	/**
-	 * 例外请求前缀的正则表达式集合(不进行权限校验)
-	 */
-	private Set<String> exclusions;
-
-	/**
-	 * 热加载配置文件
-	 *
-	 * @author WANGWEI
-	 * @param resourceName
-	 */
-	public synchronized void configure(String resourceName) {
-		if (RESOURCE_NAME_SET.contains(resourceName)) {
-			return;
-		}
-		String path = PathUtil.getResoucePath(resourceName);
-		loadFromFile(path);
-
-		RESOURCE_NAME_SET.add(resourceName);
-	}
-
 	/**
 	 * 判断是否有请求权限
 	 *
@@ -102,34 +65,17 @@ public abstract class RequestPermissionInterceptor implements HandlerInterceptor
 			Object handler) throws Exception {
 		LOG.debug("preHandle... ...");
 
-		Class<?> ctrClass = (Class<?>) request.getAttribute("$ctrClass");
+		ApiInfo apiInfo = (ApiInfo) request
+				.getAttribute(HttpServletRequestAttribute.$_API_INFO.name());
+
+		Class<?> ctrClass = apiInfo.getBeanType();
 		if (CloudService.class.isAssignableFrom(ctrClass)
 				|| EnterpriseService.class.isAssignableFrom(ctrClass)) {
 			return true;
 		}
 
-		String mappingPath = (String) request.getAttribute("$mappingPath");
-
-		if ("[runtime][][GET]".equals(mappingPath)) {
-			return true;
-		}
-
-		if (mappingPath.startsWith("[${server.error.path:${error.path:/error}}][]")) {
-			response.setStatus(HttpStatus.NOT_FOUND.value());
-			ServletUtil.returnJson(new StatusResponse("404", "not found."), response);
-			return false;
-		}
-
-		if (CollectionUtils.isNotEmpty(exclusions)) {
-			for (String e : exclusions) {
-				if (mappingPath.matches(e)) {
-					if (INTERFACE_LOG.isDebugEnabled()) {
-						INTERFACE_LOG.debug("No authentication. mapping=" + mappingPath);
-					}
-					return true;
-				}
-			}
-		}
+		String mapping = (String) request
+				.getAttribute(HttpServletRequestAttribute.$_MAPPING.name());
 
 		String key = null;
 		String token = null;
@@ -150,6 +96,17 @@ public abstract class RequestPermissionInterceptor implements HandlerInterceptor
 			token = request.getParameter("$token");
 		}
 
+		if (StringUtils.isBlank(key) || StringUtils.isBlank(token)) {
+			boolean naked = resourceManager.isNaked(apiInfo, mapping);
+			if (naked) {
+				return true;
+			} else {
+				response.setStatus(HttpStatus.FORBIDDEN.value());
+				ServletUtil.returnJson(new StatusResponse("403", "unallowed"), response);
+				return false;
+			}
+		}
+
 		if (StringUtils.isBlank(key)) {
 			response.setStatus(HttpStatus.FORBIDDEN.value());
 			ServletUtil.returnJson(new StatusResponse("403", "key is blank."), response);
@@ -161,13 +118,7 @@ public abstract class RequestPermissionInterceptor implements HandlerInterceptor
 			return false;
 		}
 
-		Integer sessionTimeout = redisClient.get("$_SESSION_TIMEOUT", Integer.class);
-		User user = null;
-		if (null == sessionTimeout) {
-			user = redisClient.get(key, User.class);
-		} else {
-			user = redisClient.get(key, User.class, sessionTimeout);
-		}
+		User user = redisClient.get(key, User.class);
 
 		if (null == user) {
 			response.setStatus(HttpStatus.FORBIDDEN.value());
@@ -179,15 +130,17 @@ public abstract class RequestPermissionInterceptor implements HandlerInterceptor
 			return false;
 		}
 
-		MDC.put("KEY", key);
+		redisClient.expire(key, user.getSessionTimeout());
+
+		ThreadContext.put("CALLER", key);
 
-		if (!hasPermission(mappingPath, user)) {
+		if (!resourceManager.hasPermission(user, apiInfo, mapping)) {
 			response.setStatus(HttpStatus.METHOD_NOT_ALLOWED.value());
 			ServletUtil.returnJson(new StatusResponse("405", "no permission."), response);
 			return false;
 		}
 
-		request.setAttribute("$accessUser", user);
+		request.setAttribute(HttpServletRequestAttribute.$_ACCESS_USER.name(), user);
 		request.setAttribute("$kt", key + ":" + token);
 
 		return true;
@@ -205,32 +158,8 @@ public abstract class RequestPermissionInterceptor implements HandlerInterceptor
 		LOG.debug("afterCompletion... ...");
 	}
 
-	/**
-	 * 加载配置项
-	 *
-	 * @author WANGWEI
-	 * @param path
-	 */
-	private void loadFromFile(String path) {
-		try {
-			Set<String> newExclusions = Sets.newHashSet();
-			List<String> lines = FileUtils.readLines(new File(path), "UTF-8");
-			for (String cur : lines) {
-				if (StringUtils.isNotBlank(cur)) {
-					cur = cur.trim();
-					if (cur.startsWith("regexp:")) {
-						cur = StringUtils.replace(cur, "regexp:", "", 1);
-					} else {
-						cur = RegExpUtil.escape(cur);
-					}
-					newExclusions.add(cur.trim());
-				}
-			}
-			exclusions = newExclusions;
-			LOG.info("exclusions=" + JsonUtil.toJson(exclusions));
-		} catch (IOException e) {
-			LOG.error("fail to load config from file. filePath=" + path, e);
-		}
+	public void setResourceManager(ResourceManager resourceManager) {
+		this.resourceManager = resourceManager;
 	}
 
 }

+ 1 - 1
src/main/java/cn/com/qmth/examcloud/web/security/ResourceManager.java

@@ -2,7 +2,7 @@ package cn.com.qmth.examcloud.web.security;
 
 import cn.com.qmth.examcloud.api.commons.security.bean.AccessApp;
 import cn.com.qmth.examcloud.api.commons.security.bean.User;
-import springfox.documentation.service.ApiInfo;
+import cn.com.qmth.examcloud.web.support.ApiInfo;
 
 /**
  * 资源管理器

+ 6 - 1
src/main/java/cn/com/qmth/examcloud/web/security/SpringCloudInterceptor.java

@@ -16,6 +16,8 @@ import cn.com.qmth.examcloud.commons.logging.ExamCloudLogFactory;
 import cn.com.qmth.examcloud.commons.util.ByteUtil;
 import cn.com.qmth.examcloud.commons.util.SHA256;
 import cn.com.qmth.examcloud.commons.util.StringUtil;
+import cn.com.qmth.examcloud.web.enums.HttpServletRequestAttribute;
+import cn.com.qmth.examcloud.web.support.ApiInfo;
 import cn.com.qmth.examcloud.web.support.ServletUtil;
 import cn.com.qmth.examcloud.web.support.StatusResponse;
 
@@ -38,7 +40,10 @@ public final class SpringCloudInterceptor implements HandlerInterceptor {
 			Object handler) throws Exception {
 		LOG.debug("preHandle... ...");
 
-		Class<?> ctrClass = (Class<?>) request.getAttribute("$ctrClass");
+		ApiInfo apiInfo = (ApiInfo) request
+				.getAttribute(HttpServletRequestAttribute.$_API_INFO.name());
+		Class<?> ctrClass = apiInfo.getBeanType();
+
 		if (!CloudService.class.isAssignableFrom(ctrClass)) {
 			return true;
 		}

+ 3 - 2
src/main/java/cn/com/qmth/examcloud/web/support/ControllerSupport.java

@@ -30,6 +30,7 @@ import cn.com.qmth.examcloud.commons.exception.StatusException;
 import cn.com.qmth.examcloud.commons.logging.ExamCloudLog;
 import cn.com.qmth.examcloud.commons.logging.ExamCloudLogFactory;
 import cn.com.qmth.examcloud.commons.util.ObjectUtil;
+import cn.com.qmth.examcloud.web.enums.HttpServletRequestAttribute;
 
 /**
  * contorller 基类
@@ -50,7 +51,7 @@ public abstract class ControllerSupport {
 	 * @return
 	 */
 	protected User getAccessUser() {
-		User accessUser = (User) ServletUtil.getRequest().getAttribute("$accessUser");
+		User accessUser = (User) ServletUtil.getRequest().getAttribute(HttpServletRequestAttribute.$_ACCESS_USER.name());
 		if (null == accessUser) {
 			throw new StatusException("252", "请重新登陆");
 		}
@@ -63,7 +64,7 @@ public abstract class ControllerSupport {
 	 * @author WANGWEI
 	 */
 	protected void setAlwaysOKResponse() {
-		ServletUtil.getRequest().setAttribute("$ALWAYS_OK", true);
+		ServletUtil.getRequest().setAttribute(HttpServletRequestAttribute.$_ALWAYS_OK.name(), true);
 	}
 
 	/**