wangwei 7 years ago
parent
commit
7baa494983

+ 40 - 1
examcloud-exchange-starter/src/main/java/cn/com/qmth/examcloud/exchange/config/DefaultWebMvcConfigurerAdapter.java

@@ -1,5 +1,9 @@
 package cn.com.qmth.examcloud.exchange.config;
 package cn.com.qmth.examcloud.exchange.config;
 
 
+import java.util.List;
+
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Configuration;
@@ -11,7 +15,10 @@ import cn.com.qmth.examcloud.commons.base.util.PropertiesUtil;
 import cn.com.qmth.examcloud.commons.web.interceptor.FirstInterceptor;
 import cn.com.qmth.examcloud.commons.web.interceptor.FirstInterceptor;
 import cn.com.qmth.examcloud.commons.web.redis.RedisClient;
 import cn.com.qmth.examcloud.commons.web.redis.RedisClient;
 import cn.com.qmth.examcloud.commons.web.security.RequestPermissionInterceptor;
 import cn.com.qmth.examcloud.commons.web.security.RequestPermissionInterceptor;
+import cn.com.qmth.examcloud.commons.web.security.SpringCloudInterceptor;
+import cn.com.qmth.examcloud.commons.web.security.bean.Role;
 import cn.com.qmth.examcloud.commons.web.security.bean.User;
 import cn.com.qmth.examcloud.commons.web.security.bean.User;
+import cn.com.qmth.examcloud.core.basic.api.CommonCloudService;
 
 
 /**
 /**
  * 默认WebMvcConfigurer
  * 默认WebMvcConfigurer
@@ -26,6 +33,9 @@ public class DefaultWebMvcConfigurerAdapter extends WebMvcConfigurerAdapter {
 	@Autowired
 	@Autowired
 	RedisClient redisClient;
 	RedisClient redisClient;
 
 
+	@Autowired
+	CommonCloudService commonCloudService;
+
 	static {
 	static {
 		PropertiesUtil.configureAndWatch(PathUtil.getResoucePath("security-mapping.properties"));
 		PropertiesUtil.configureAndWatch(PathUtil.getResoucePath("security-mapping.properties"));
 	}
 	}
@@ -33,9 +43,20 @@ public class DefaultWebMvcConfigurerAdapter extends WebMvcConfigurerAdapter {
 	@Override
 	@Override
 	public void addInterceptors(InterceptorRegistry registry) {
 	public void addInterceptors(InterceptorRegistry registry) {
 		registry.addInterceptor(new FirstInterceptor()).addPathPatterns("/**");
 		registry.addInterceptor(new FirstInterceptor()).addPathPatterns("/**");
+
+		SpringCloudInterceptor springCloudInterceptor = new SpringCloudInterceptor();
+		springCloudInterceptor.setRedisClient(redisClient);
+		registry.addInterceptor(springCloudInterceptor).addPathPatterns("/**");
+
+		ThirdPartyAccessInterceptor thirdPartyAccessInterceptor = new ThirdPartyAccessInterceptor();
+		thirdPartyAccessInterceptor.setRedisClient(redisClient);
+		thirdPartyAccessInterceptor.setCommonCloudService(commonCloudService);
+		registry.addInterceptor(thirdPartyAccessInterceptor).addPathPatterns("/**");
+
 		RequestPermissionInterceptor requestPermissionInterceptor = getRequestPermissionInterceptor();
 		RequestPermissionInterceptor requestPermissionInterceptor = getRequestPermissionInterceptor();
 		requestPermissionInterceptor.configureAndWatch("security-exclusions.conf");
 		requestPermissionInterceptor.configureAndWatch("security-exclusions.conf");
 		registry.addInterceptor(requestPermissionInterceptor).addPathPatterns("/**");
 		registry.addInterceptor(requestPermissionInterceptor).addPathPatterns("/**");
+
 		super.addInterceptors(registry);
 		super.addInterceptors(registry);
 	}
 	}
 
 
@@ -45,7 +66,25 @@ public class DefaultWebMvcConfigurerAdapter extends WebMvcConfigurerAdapter {
 
 
 			@Override
 			@Override
 			public boolean hasPermission(String mappingPath, User user) {
 			public boolean hasPermission(String mappingPath, User user) {
-				return true;
+				List<Role> roleList = user.getRoleList();
+				if (CollectionUtils.isEmpty(roleList)) {
+					return false;
+				}
+
+				String roles = PropertiesUtil.getString(mappingPath);
+				if (StringUtils.isBlank(roles)) {
+					return true;
+				}
+
+				roles = "," + roles + ",";
+
+				for (Role role : roleList) {
+					if (roles.contains("," + role.getRoleCode() + ",")) {
+						return true;
+					}
+				}
+
+				return false;
 			}
 			}
 
 
 		};
 		};

+ 159 - 0
examcloud-exchange-starter/src/main/java/cn/com/qmth/examcloud/exchange/config/ThirdPartyAccessInterceptor.java

@@ -0,0 +1,159 @@
+package cn.com.qmth.examcloud.exchange.config;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.servlet.HandlerInterceptor;
+import org.springframework.web.servlet.ModelAndView;
+
+import cn.com.qmth.examcloud.commons.base.exception.StatusException;
+import cn.com.qmth.examcloud.commons.base.logging.ExamCloudLog;
+import cn.com.qmth.examcloud.commons.base.logging.ExamCloudLogFactory;
+import cn.com.qmth.examcloud.commons.base.util.ByteUtil;
+import cn.com.qmth.examcloud.commons.base.util.SHA256;
+import cn.com.qmth.examcloud.commons.base.util.StringUtil;
+import cn.com.qmth.examcloud.commons.web.redis.RedisClient;
+import cn.com.qmth.examcloud.commons.web.support.ServletUtil;
+import cn.com.qmth.examcloud.commons.web.support.StatusResponseEntity;
+import cn.com.qmth.examcloud.core.basic.api.CommonCloudService;
+import cn.com.qmth.examcloud.core.basic.api.bean.ThirdPartyAccessBean;
+import cn.com.qmth.examcloud.core.basic.api.request.GetThirdPartyAccessInfoReq;
+import cn.com.qmth.examcloud.core.basic.api.response.GetThirdPartyAccessInfoResp;
+
+/**
+ * 第三方请求接入
+ *
+ * @author WANGWEI
+ * @date 2018年5月22日
+ * @Copyright (c) 2018-? http://qmth.com.cn All Rights Reserved.
+ */
+public final class ThirdPartyAccessInterceptor implements HandlerInterceptor {
+
+	private static final ExamCloudLog LOG = ExamCloudLogFactory
+			.getLog(ThirdPartyAccessInterceptor.class);
+
+	/**
+	 * 接口日志
+	 */
+	protected static final ExamCloudLog INTERFACE_LOG = ExamCloudLogFactory
+			.getLog("INTERFACE_LOGGER");
+
+	/**
+	 * redis client
+	 */
+	private RedisClient redisClient;
+
+	private CommonCloudService commonCloudService;
+
+	@Override
+	public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
+			Object handler) throws Exception {
+		LOG.debug("preHandle... ...");
+
+		String accessToken = request.getHeader("access_token");
+		if (null == accessToken) {
+			return true;
+		}
+
+		String rootOrgId = request.getHeader("rootOrgId");
+		String appId = request.getHeader("appId");
+		String timestamp = request.getHeader("timestamp");
+
+		if (StringUtils.isBlank(rootOrgId) || StringUtils.isBlank(appId)
+				|| StringUtils.isBlank(timestamp)) {
+			response.setStatus(HttpStatus.FORBIDDEN.value());
+			ServletUtil.returnJson(
+					new StatusResponseEntity("403",
+							"第三方接入请求必须包含请求头['access_token','rootOrgId','appId','timestamp']"),
+					response);
+			return false;
+		}
+
+		accessToken = accessToken.trim();
+		rootOrgId = rootOrgId.trim();
+		appId = appId.trim();
+		timestamp = timestamp.trim();
+
+		if (!(StringUtil.isLong(rootOrgId) && StringUtil.isLong(timestamp))) {
+			response.setStatus(HttpStatus.FORBIDDEN.value());
+			ServletUtil.returnJson(
+					new StatusResponseEntity("403", "第三方接入请求头['rootOrgId','timestamp']必须是整数"),
+					response);
+			return false;
+		}
+
+		String key = "A_" + rootOrgId + appId;
+
+		ThirdPartyAccessBean thirdPartyAccessBean = redisClient.get(key, ThirdPartyAccessBean.class,
+				60000);
+
+		if (null == thirdPartyAccessBean) {
+			try {
+				thirdPartyAccessBean = getThirdPartyAccessInfo(rootOrgId, appId);
+			} catch (StatusException e) {
+				response.setStatus(HttpStatus.FORBIDDEN.value());
+				ServletUtil.returnJson(new StatusResponseEntity("403", e.getDesc()), response);
+				return false;
+			} catch (Exception e) {
+				response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
+				ServletUtil.returnJson(new StatusResponseEntity("500", "获取第三方接入信息异常"), response);
+				return false;
+			}
+			redisClient.set(key, thirdPartyAccessBean, 60000);
+		}
+
+		long timestampLong = Long.parseLong(timestamp);
+
+		long currentTimeMillis = System.currentTimeMillis();
+		if (Math.abs(currentTimeMillis - timestampLong) > thirdPartyAccessBean.getTimeRange()) {
+			throw new StatusException("B-001203", "timestamp超出时间差范围");
+		}
+
+		String secretKey = thirdPartyAccessBean.getSecretKey();
+		String joinStr = StringUtil.join(rootOrgId, appId, timestamp, secretKey);
+		byte[] bytes = SHA256.encode(joinStr);
+		String hexAscii = ByteUtil.toHexAscii(bytes);
+
+		if (!hexAscii.equalsIgnoreCase(accessToken)) {
+			response.setStatus(HttpStatus.FORBIDDEN.value());
+			ServletUtil.returnJson(new StatusResponseEntity("403", "access_token校验失败"), response);
+			return false;
+		}
+
+		request.setAttribute("$no_session_access", true);
+		return true;
+	}
+
+	private ThirdPartyAccessBean getThirdPartyAccessInfo(String rootOrgId, String appId) {
+		ThirdPartyAccessBean thirdPartyAccessBean;
+		GetThirdPartyAccessInfoReq req = new GetThirdPartyAccessInfoReq();
+		req.setAppId(appId);
+		req.setRootOrgId(Long.parseLong(rootOrgId));
+		GetThirdPartyAccessInfoResp resp = commonCloudService.getThirdPartyAccessInfo(req);
+		thirdPartyAccessBean = resp.getThirdPartyAccessBean();
+		return thirdPartyAccessBean;
+	}
+
+	@Override
+	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
+			ModelAndView modelAndView) throws Exception {
+		LOG.debug("postHandle... ...");
+	}
+
+	@Override
+	public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
+			Object handler, Exception ex) throws Exception {
+		LOG.debug("afterCompletion... ...");
+	}
+
+	public void setRedisClient(RedisClient redisClient) {
+		this.redisClient = redisClient;
+	}
+
+	public void setCommonCloudService(CommonCloudService commonCloudService) {
+		this.commonCloudService = commonCloudService;
+	}
+
+}