|
@@ -0,0 +1,244 @@
|
|
|
+package com.qmth.themis.business.util;
|
|
|
+
|
|
|
+import com.google.gson.Gson;
|
|
|
+import com.qmth.themis.business.constant.SpringContextHolder;
|
|
|
+import com.qmth.themis.business.constant.SystemConstant;
|
|
|
+import com.qmth.themis.business.dto.AuthDto;
|
|
|
+import com.qmth.themis.business.dto.cache.TEStudentCacheDto;
|
|
|
+import com.qmth.themis.business.entity.TBSession;
|
|
|
+import com.qmth.themis.business.entity.TBUser;
|
|
|
+import com.qmth.themis.business.entity.TEStudent;
|
|
|
+import com.qmth.themis.business.service.CacheService;
|
|
|
+import com.qmth.themis.business.service.TBUserService;
|
|
|
+import com.qmth.themis.business.service.TEStudentService;
|
|
|
+import com.qmth.themis.common.enums.ExceptionResultEnum;
|
|
|
+import com.qmth.themis.common.enums.Platform;
|
|
|
+import com.qmth.themis.common.exception.BusinessException;
|
|
|
+import com.qmth.themis.common.signature.SignatureInfo;
|
|
|
+import com.qmth.themis.common.signature.SignatureType;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.slf4j.Logger;
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
+
|
|
|
+import javax.servlet.http.HttpServletRequest;
|
|
|
+import javax.servlet.http.HttpServletResponse;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Objects;
|
|
|
+import java.util.Set;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @Description: 鉴权工具类util
|
|
|
+ * @Param:
|
|
|
+ * @return:
|
|
|
+ * @Author: wangliang
|
|
|
+ * @Date: 2020/11/12
|
|
|
+ */
|
|
|
+public class AuthUtil {
|
|
|
+ private final static Logger log = LoggerFactory.getLogger(AuthUtil.class);
|
|
|
+
|
|
|
+ /**
|
|
|
+ * admin鉴权
|
|
|
+ *
|
|
|
+ * @param platform
|
|
|
+ * @param deviceId
|
|
|
+ * @param authorization
|
|
|
+ * @param time
|
|
|
+ * @param sysUrls
|
|
|
+ * @param request
|
|
|
+ * @param response
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static boolean adminAuthInterceptor(Platform platform,
|
|
|
+ String deviceId,
|
|
|
+ String authorization,
|
|
|
+ String time,
|
|
|
+ List<String> sysUrls,
|
|
|
+ HttpServletRequest request,
|
|
|
+ HttpServletResponse response) {
|
|
|
+ RedisUtil redisUtil = SpringContextHolder.getBean(RedisUtil.class);
|
|
|
+ TBUserService tbUserService = SpringContextHolder.getBean(TBUserService.class);
|
|
|
+ String url = request.getServletPath();
|
|
|
+ String method = request.getMethod();
|
|
|
+ TBSession tbSession = authHeadCommon(redisUtil, platform, deviceId, authorization, time, method, url);
|
|
|
+ long userId = Long.parseLong(tbSession.getIdentity());
|
|
|
+ TBUser tbUser = (TBUser) redisUtil.getUser(userId);
|
|
|
+ if (Objects.isNull(tbUser)) {
|
|
|
+ tbUser = tbUserService.getById(userId);
|
|
|
+ redisUtil.setUser(tbUser.getId(), tbUser);
|
|
|
+ }
|
|
|
+ request.setAttribute(SystemConstant.SESSION, tbSession);
|
|
|
+ request.setAttribute(SystemConstant.ACCOUNT, tbUser);
|
|
|
+ return authFootCommon(redisUtil, userId, SystemConstant.userOauth, sysUrls, request, response);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * exam鉴权
|
|
|
+ *
|
|
|
+ * @param platform
|
|
|
+ * @param deviceId
|
|
|
+ * @param authorization
|
|
|
+ * @param time
|
|
|
+ * @param sysUrls
|
|
|
+ * @param request
|
|
|
+ * @param response
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static boolean examAuthInterceptor(Platform platform,
|
|
|
+ String deviceId,
|
|
|
+ String authorization,
|
|
|
+ String time,
|
|
|
+ List<String> sysUrls,
|
|
|
+ HttpServletRequest request,
|
|
|
+ HttpServletResponse response) {
|
|
|
+ RedisUtil redisUtil = SpringContextHolder.getBean(RedisUtil.class);
|
|
|
+ TEStudentService teStudentService = SpringContextHolder.getBean(TEStudentService.class);
|
|
|
+ String url = request.getServletPath();
|
|
|
+ String method = request.getMethod();
|
|
|
+ TBSession tbSession = authHeadCommon(redisUtil, platform, deviceId, authorization, time, method, url);
|
|
|
+ long userId = Long.parseLong(tbSession.getIdentity());
|
|
|
+ TEStudentCacheDto teStudentCacheDto = (TEStudentCacheDto) redisUtil.getStudent(userId);
|
|
|
+ if (Objects.isNull(teStudentCacheDto)) {
|
|
|
+ TEStudent teStudent = teStudentService.getById(userId);
|
|
|
+ Gson gson = new Gson();
|
|
|
+ teStudentCacheDto = gson.fromJson(gson.toJson(teStudent), TEStudentCacheDto.class);
|
|
|
+ redisUtil.setStudent(teStudent.getId(), teStudentCacheDto);
|
|
|
+ }
|
|
|
+ request.setAttribute(SystemConstant.SESSION, tbSession);
|
|
|
+ request.setAttribute(SystemConstant.STUDENT_ACCOUNT, teStudentCacheDto);
|
|
|
+ return authFootCommon(redisUtil, userId, SystemConstant.studentOauth, sysUrls, request, response);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * websocket鉴权
|
|
|
+ *
|
|
|
+ * @param platform
|
|
|
+ * @param deviceId
|
|
|
+ * @param authorization
|
|
|
+ * @param time
|
|
|
+ * @param method
|
|
|
+ * @param url
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static TBSession websocketAuthInterceptor(Platform platform,
|
|
|
+ String deviceId,
|
|
|
+ String authorization,
|
|
|
+ String time,
|
|
|
+ String method,
|
|
|
+ String url) {
|
|
|
+ RedisUtil redisUtil = SpringContextHolder.getBean(RedisUtil.class);
|
|
|
+ return authHeadCommon(redisUtil, platform, deviceId, authorization, time, method, url);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 鉴权头公用
|
|
|
+ *
|
|
|
+ * @param redisUtil
|
|
|
+ * @param platform
|
|
|
+ * @param deviceId
|
|
|
+ * @param authorization
|
|
|
+ * @param time
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ static TBSession authHeadCommon(RedisUtil redisUtil,
|
|
|
+ Platform platform,
|
|
|
+ String deviceId,
|
|
|
+ String authorization,
|
|
|
+ String time,
|
|
|
+ String method,
|
|
|
+ String url) {
|
|
|
+ long timestamp = StringUtils.isNumeric(time) ? Long.parseLong(time) : 0L;
|
|
|
+// if (SystemConstant.expire(timestamp)) {
|
|
|
+// log.warn("Authorization faile: time expired, server time=" + System.currentTimeMillis());
|
|
|
+// throw new BusinessException(ExceptionResultEnum.AUTHORIZATION_ERROR);
|
|
|
+// }
|
|
|
+ //测试
|
|
|
+ final SignatureInfo info = SignatureInfo.parse(authorization);
|
|
|
+ //校验签名信息
|
|
|
+// final SignatureInfo info = SignatureInfo.parse(method.toLowerCase(), url, timestamp, authorization);
|
|
|
+ if (info == null) {
|
|
|
+ log.warn("Authorization faile: signature decode error");
|
|
|
+ throw new BusinessException(ExceptionResultEnum.AUTHORIZATION_ERROR);
|
|
|
+ }
|
|
|
+ if (SignatureType.TOKEN != info.getType()) {
|
|
|
+ log.warn("Authorization faile: signature type is not Token");
|
|
|
+ throw new BusinessException(ExceptionResultEnum.AUTHORIZATION_ERROR);
|
|
|
+ }
|
|
|
+ //校验session
|
|
|
+ String sessionId = info.getInvoker();
|
|
|
+ TBSession tbSession = (TBSession) redisUtil.getUserSession(sessionId);
|
|
|
+ if (Objects.isNull(tbSession)) {
|
|
|
+ log.warn("Authorization faile: session id not exists: " + sessionId);
|
|
|
+ throw new BusinessException(ExceptionResultEnum.LOGIN_NO);
|
|
|
+ }
|
|
|
+ if (tbSession.getExpireTime() <= System.currentTimeMillis() || info.getTimestamp() > tbSession.getExpireTime()) {
|
|
|
+ log.warn("Authorization faile: session has expired, expire time=" + tbSession.getExpireTime());
|
|
|
+ throw new BusinessException(ExceptionResultEnum.LOGIN_NO);
|
|
|
+ }
|
|
|
+ if (!info.validate(tbSession.getAccessToken())) {
|
|
|
+ log.warn("Authorization faile: access token invalid, session token is " + tbSession.getAccessToken());
|
|
|
+ throw new BusinessException(ExceptionResultEnum.AUTHORIZATION_ERROR);
|
|
|
+ }
|
|
|
+ if (!tbSession.getPlatform().equalsIgnoreCase(platform.name())) {
|
|
|
+ log.warn("Authorization faile: platform invalid, session platform is " + tbSession.getPlatform());
|
|
|
+ throw new BusinessException(ExceptionResultEnum.AUTHORIZATION_ERROR);
|
|
|
+ }
|
|
|
+ if (!tbSession.getDeviceId().equalsIgnoreCase(deviceId)) {
|
|
|
+ log.warn("Authorization faile: deviceId invalid, session deviceId is " + tbSession.getDeviceId());
|
|
|
+ throw new BusinessException(ExceptionResultEnum.AUTHORIZATION_ERROR);
|
|
|
+ }
|
|
|
+ return tbSession;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 鉴权尾公用
|
|
|
+ *
|
|
|
+ * @param redisUtil
|
|
|
+ * @param userId
|
|
|
+ * @param type
|
|
|
+ * @param sysUrls
|
|
|
+ * @param request
|
|
|
+ * @param response
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ static boolean authFootCommon(RedisUtil redisUtil,
|
|
|
+ long userId,
|
|
|
+ String type,
|
|
|
+ List<String> sysUrls,
|
|
|
+ HttpServletRequest request,
|
|
|
+ HttpServletResponse response) {
|
|
|
+ String url = request.getServletPath();
|
|
|
+ CacheService cacheService = SpringContextHolder.getBean(CacheService.class);
|
|
|
+ AuthDto authDto = (AuthDto) redisUtil.get(type + userId);
|
|
|
+ //验证权限
|
|
|
+ if (Objects.isNull(authDto)) {
|
|
|
+ if (type.contains(SystemConstant.userOauth)) {
|
|
|
+ authDto = cacheService.addAccountCache(userId);
|
|
|
+ } else if (type.contains(SystemConstant.studentOauth)) {
|
|
|
+ authDto = cacheService.addStudentCache(userId);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ request.setAttribute(SystemConstant.ORG, authDto.getTbOrg());
|
|
|
+
|
|
|
+ //系统管理员拥有所有权限
|
|
|
+// if (authDto.getRoleCodes().contains(RoleEnum.SUPER_ADMIN.name())) {
|
|
|
+// return true;
|
|
|
+// }
|
|
|
+ //系统公用接口不拦截
|
|
|
+ int sysCount = (int) sysUrls.stream().filter(s -> {
|
|
|
+ return s.equalsIgnoreCase(url);
|
|
|
+ }).count();
|
|
|
+ if (sysCount > 0) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ Set<String> urls = authDto.getUrls();
|
|
|
+ int count = (int) urls.stream().filter(s -> {
|
|
|
+ return s.equalsIgnoreCase(url);
|
|
|
+ }).count();
|
|
|
+ if (count == 0) {
|
|
|
+ log.warn("Authorization faile: url cannot access");
|
|
|
+ throw new BusinessException(ExceptionResultEnum.UN_AUTHORIZATION);
|
|
|
+ }
|
|
|
+ response.setStatus(ExceptionResultEnum.SUCCESS.getCode());
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+}
|