|
@@ -6,16 +6,16 @@ import com.qmth.themis.business.constant.SystemConstant;
|
|
|
import com.qmth.themis.business.dto.AuthDto;
|
|
|
import com.qmth.themis.business.entity.TBSession;
|
|
|
import com.qmth.themis.business.entity.TBUser;
|
|
|
-import com.qmth.themis.business.enums.RoleEnum;
|
|
|
import com.qmth.themis.business.service.EhcacheService;
|
|
|
import com.qmth.themis.business.service.TBUserService;
|
|
|
import com.qmth.themis.business.util.EhcacheUtil;
|
|
|
-import com.qmth.themis.business.util.JwtUtil;
|
|
|
import com.qmth.themis.business.util.RedisUtil;
|
|
|
-import com.qmth.themis.business.util.SessionUtil;
|
|
|
+import com.qmth.themis.common.contanst.Constants;
|
|
|
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.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
import org.springframework.web.servlet.HandlerInterceptor;
|
|
@@ -52,71 +52,80 @@ public class AuthInterceptor implements HandlerInterceptor {
|
|
|
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) throws Exception {
|
|
|
log.info("HandlerInterceptor preHandle is come in");
|
|
|
String url = request.getServletPath();
|
|
|
- if (url.equalsIgnoreCase("/error")) {
|
|
|
- if (response.getStatus() == cn.hutool.http.HttpStatus.HTTP_NOT_FOUND) {
|
|
|
- throw new BusinessException(ExceptionResultEnum.NOT_FOUND);
|
|
|
- } else {
|
|
|
- throw new BusinessException(ExceptionResultEnum.EXCEPTION_ERROR);
|
|
|
- }
|
|
|
- }
|
|
|
- String token = ServletUtil.getRequestToken(request);
|
|
|
+ String method = request.getMethod();
|
|
|
Platform platform = Platform.valueOf(ServletUtil.getRequestPlatform(request));
|
|
|
String deviceId = ServletUtil.getRequestDeviceId(request);
|
|
|
- if (Objects.isNull(token) || Objects.equals(token, "")) {
|
|
|
- throw new BusinessException(ExceptionResultEnum.TOKEN_INVALID);
|
|
|
- }
|
|
|
if (Objects.isNull(platform) || Objects.equals(platform, "")) {
|
|
|
throw new BusinessException(ExceptionResultEnum.PLATFORM_INVALID);
|
|
|
}
|
|
|
if (Objects.isNull(deviceId) || Objects.equals(deviceId, "")) {
|
|
|
throw new BusinessException(ExceptionResultEnum.DEVICE_ID_INVALID);
|
|
|
}
|
|
|
- Long userId = Long.parseLong(JwtUtil.getClaim(token, SystemConstant.JWT_USERID));
|
|
|
- String role = JwtUtil.getClaim(token, SystemConstant.ROLE);
|
|
|
- //首先验证token是否匹配
|
|
|
- if (!JwtUtil.verify(token, userId, platform, deviceId, RoleEnum.valueOf(role))) {
|
|
|
- throw new BusinessException(ExceptionResultEnum.TOKEN_NO);
|
|
|
- }
|
|
|
- //系统公用接口不拦截
|
|
|
- List<String> sysUrls = dictionaryConfig.systemUrlDomain().getUrls();
|
|
|
- int sysCount = (int) sysUrls.stream().filter(s -> {
|
|
|
- return s.equalsIgnoreCase(url);
|
|
|
- }).count();
|
|
|
- if (sysCount > 0) {
|
|
|
- return true;
|
|
|
- }
|
|
|
- //验证token是否有效
|
|
|
- String sessionId = SessionUtil.digest(userId, RoleEnum.valueOf(role), platform.getSource());
|
|
|
- TBSession tbSession = (TBSession) RedisUtil.getUserSession(sessionId);
|
|
|
- if (Objects.isNull(tbSession)) {
|
|
|
- throw new BusinessException(ExceptionResultEnum.LOGIN_NO);
|
|
|
- } else {
|
|
|
- if (!Objects.equals(token, tbSession.getAccessToken())) {
|
|
|
- throw new BusinessException(ExceptionResultEnum.TOKEN_NO);
|
|
|
- }
|
|
|
- Date expireTime = tbSession.getExpireTime();
|
|
|
- //手机端的token时长为一个月,所以会出现缓存没有的情况
|
|
|
- TBUser tbUser = (TBUser) RedisUtil.getUser(userId);
|
|
|
- if (Objects.isNull(tbUser)) {
|
|
|
- tbUser = tbUserService.getById(userId);
|
|
|
- RedisUtil.setUser(tbUser.getId(), tbUser);
|
|
|
- }
|
|
|
- //还剩5分钟刷新会话缓存
|
|
|
- if (Objects.nonNull(expireTime) && (expireTime.getTime() - System.currentTimeMillis()) <= SystemConstant.REFRESH_EXPIRE_TIME) {
|
|
|
- RedisUtil.refreshUserSession(sessionId);
|
|
|
+ if (url.equalsIgnoreCase("/error")) {
|
|
|
+ if (response.getStatus() == cn.hutool.http.HttpStatus.HTTP_NOT_FOUND) {
|
|
|
+ throw new BusinessException(ExceptionResultEnum.NOT_FOUND);
|
|
|
+ } else {
|
|
|
+ throw new BusinessException(ExceptionResultEnum.EXCEPTION_ERROR);
|
|
|
}
|
|
|
}
|
|
|
- AuthDto authDto = (AuthDto) EhcacheUtil.get(SystemConstant.AUTH_CACHE, userId);
|
|
|
- if (Objects.isNull(authDto)) {
|
|
|
- authDto = ehcacheService.addAccountCache(userId);
|
|
|
- }
|
|
|
- //验证权限
|
|
|
- Set<String> urls = authDto.getUrls();
|
|
|
- int count = (int) urls.stream().filter(s -> {
|
|
|
- return s.equalsIgnoreCase(url);
|
|
|
- }).count();
|
|
|
- if (count == 0) {
|
|
|
- throw new BusinessException(ExceptionResultEnum.UN_AUTHORIZATION);
|
|
|
+ Long userId = null;
|
|
|
+ Long timestamp = Long.parseLong(ServletUtil.getRequestTime(request));
|
|
|
+ if (!expire(timestamp.longValue())) {
|
|
|
+ final SignatureInfo info = SignatureInfo
|
|
|
+ .parse(method, url, timestamp, ServletUtil.getRequestAuthorization(request));
|
|
|
+ if (Objects.nonNull(info) && info.getType() == SignatureType.TOKEN) {
|
|
|
+ String sessionId = info.getInvoker();
|
|
|
+ TBSession tbSession = (TBSession) RedisUtil.getUserSession(sessionId);
|
|
|
+ if (Objects.isNull(tbSession)) {
|
|
|
+ throw new BusinessException(ExceptionResultEnum.LOGIN_NO);
|
|
|
+ } else {
|
|
|
+ if (info.validate(tbSession.getAccessToken()) && info.getTimestamp() < tbSession.getExpireTime().getTime()
|
|
|
+ && platform.name().equalsIgnoreCase(tbSession.getPlatform()) && Objects.equals(deviceId, tbSession.getDeviceId())) {
|
|
|
+ userId = Long.parseLong(tbSession.getIdentity());
|
|
|
+ Date expireTime = tbSession.getExpireTime();
|
|
|
+ //手机端的token时长为一个月,所以会出现缓存没有的情况
|
|
|
+ TBUser tbUser = (TBUser) RedisUtil.getUser(userId);
|
|
|
+ if (Objects.isNull(tbUser)) {
|
|
|
+ tbUser = tbUserService.getById(userId);
|
|
|
+ RedisUtil.setUser(tbUser.getId(), tbUser);
|
|
|
+ }
|
|
|
+ //还剩5分钟刷新会话缓存
|
|
|
+ if (Objects.nonNull(expireTime) && (expireTime.getTime() - System.currentTimeMillis()) <= SystemConstant.REFRESH_EXPIRE_TIME) {
|
|
|
+ RedisUtil.refreshUserSession(sessionId);
|
|
|
+ }
|
|
|
+
|
|
|
+ request.setAttribute(SystemConstant.SESSION, tbSession);
|
|
|
+ request.setAttribute(SystemConstant.ACCOUNT, tbUser);
|
|
|
+ //系统公用接口不拦截
|
|
|
+ List<String> sysUrls = dictionaryConfig.systemUrlDomain().getUrls();
|
|
|
+ int sysCount = (int) sysUrls.stream().filter(s -> {
|
|
|
+ return s.equalsIgnoreCase(url);
|
|
|
+ }).count();
|
|
|
+ if (sysCount > 0) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ //验证权限
|
|
|
+ AuthDto authDto = (AuthDto) EhcacheUtil.get(SystemConstant.AUTH_CACHE, userId);
|
|
|
+ if (Objects.isNull(authDto)) {
|
|
|
+ authDto = ehcacheService.addAccountCache(userId);
|
|
|
+ }
|
|
|
+ Set<String> urls = authDto.getUrls();
|
|
|
+ int count = (int) urls.stream().filter(s -> {
|
|
|
+ return s.equalsIgnoreCase(url);
|
|
|
+ }).count();
|
|
|
+ if (count == 0) {
|
|
|
+ throw new BusinessException(ExceptionResultEnum.UN_AUTHORIZATION);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ throw new BusinessException(ExceptionResultEnum.AUTHORIZATION_ERROR);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ throw new BusinessException(ExceptionResultEnum.AUTHORIZATION_ERROR);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ throw new BusinessException(ExceptionResultEnum.AUTHORIZATION_ERROR);
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
@@ -133,4 +142,9 @@ public class AuthInterceptor implements HandlerInterceptor {
|
|
|
HttpServletResponse response,
|
|
|
Object o, Exception e) throws Exception {
|
|
|
}
|
|
|
+
|
|
|
+ public boolean expire(long timestamp) {
|
|
|
+ long diff = (System.currentTimeMillis() - timestamp) / 1000;
|
|
|
+ return diff < -1 * Constants.SIGNATURE_AHEAD_SECONDS || diff > Constants.SIGNATURE_EXPIRE_SECONDS;
|
|
|
+ }
|
|
|
}
|