|
@@ -1,34 +1,20 @@
|
|
|
package com.sckw.core.filter;
|
|
package com.sckw.core.filter;
|
|
|
|
|
|
|
|
-import com.alibaba.fastjson.JSON;
|
|
|
|
|
-import com.alibaba.fastjson2.JSONObject;
|
|
|
|
|
|
|
+import com.alibaba.fastjson2.JSON;
|
|
|
import com.sckw.core.model.constant.Global;
|
|
import com.sckw.core.model.constant.Global;
|
|
|
-import com.sckw.core.model.enums.ClientTypeEnum;
|
|
|
|
|
-import com.sckw.core.model.enums.SystemTypeEnum;
|
|
|
|
|
-import com.sckw.core.utils.CollectionUtils;
|
|
|
|
|
-import com.sckw.core.utils.EncryUtil;
|
|
|
|
|
-import com.sckw.core.utils.NumberUtils;
|
|
|
|
|
import com.sckw.core.utils.StringUtils;
|
|
import com.sckw.core.utils.StringUtils;
|
|
|
-import com.sckw.core.web.config.CustomConfig;
|
|
|
|
|
-import com.sckw.core.web.constant.HttpStatus;
|
|
|
|
|
-import com.sckw.core.web.constant.RequestConstant;
|
|
|
|
|
import com.sckw.core.web.context.LoginEntHolder;
|
|
import com.sckw.core.web.context.LoginEntHolder;
|
|
|
import com.sckw.core.web.context.LoginUserHolder;
|
|
import com.sckw.core.web.context.LoginUserHolder;
|
|
|
import com.sckw.core.web.model.LoginEntInfo;
|
|
import com.sckw.core.web.model.LoginEntInfo;
|
|
|
import com.sckw.core.web.model.LoginUserInfo;
|
|
import com.sckw.core.web.model.LoginUserInfo;
|
|
|
-import com.sckw.core.web.response.HttpResult;
|
|
|
|
|
-import com.sckw.core.web.response.ResponseUtil;
|
|
|
|
|
-import com.sckw.redis.utils.RedissonUtils;
|
|
|
|
|
-import jakarta.annotation.PostConstruct;
|
|
|
|
|
import jakarta.servlet.*;
|
|
import jakarta.servlet.*;
|
|
|
import jakarta.servlet.http.HttpServletRequest;
|
|
import jakarta.servlet.http.HttpServletRequest;
|
|
|
-import jakarta.servlet.http.HttpServletResponse;
|
|
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
-import org.redisson.api.RSet;
|
|
|
|
|
-import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
|
|
|
+import org.springframework.core.Ordered;
|
|
|
|
|
|
|
|
import java.io.IOException;
|
|
import java.io.IOException;
|
|
|
-import java.util.*;
|
|
|
|
|
|
|
+import java.net.URLDecoder;
|
|
|
|
|
+import java.nio.charset.StandardCharsets;
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* @desc: 登录过滤
|
|
* @desc: 登录过滤
|
|
@@ -36,222 +22,34 @@ import java.util.*;
|
|
|
* @date: 2023/6/14
|
|
* @date: 2023/6/14
|
|
|
*/
|
|
*/
|
|
|
@Slf4j
|
|
@Slf4j
|
|
|
-public class RequestCheckFilter implements Filter {
|
|
|
|
|
|
|
+public class RequestCheckFilter implements Filter, Ordered {
|
|
|
|
|
|
|
|
- @Autowired
|
|
|
|
|
- CustomConfig customConfig;
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * 直接放行不需要校验Access-Token的请求
|
|
|
|
|
- */
|
|
|
|
|
- private static final List<String> EXCLUDEPATH = new ArrayList<>();
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * 直接放行不需要校验Access-Special的请求
|
|
|
|
|
- */
|
|
|
|
|
- private static final List<String> IMPORT_PASS_PATH = new ArrayList<>();
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * 需要校验token但不用接口权限校验的请求
|
|
|
|
|
- */
|
|
|
|
|
- private static final List<String> WITHOUTPATH = new ArrayList<>();
|
|
|
|
|
-
|
|
|
|
|
- private static final String REGISTER = "/kwsEnt/register";
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * @desc: 初始化放行路径
|
|
|
|
|
- * @author: czh
|
|
|
|
|
- */
|
|
|
|
|
- @PostConstruct
|
|
|
|
|
- private void initExcludePath() {
|
|
|
|
|
- String links = customConfig.getLinks();
|
|
|
|
|
- if (StringUtils.isNotBlank(links)) {
|
|
|
|
|
- EXCLUDEPATH.addAll(Arrays.asList(links.split(Global.COMMA)));
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- String specialLinks = customConfig.getSpecialLinks();
|
|
|
|
|
- if (StringUtils.isNotBlank(specialLinks)) {
|
|
|
|
|
- IMPORT_PASS_PATH.addAll(Arrays.asList(links.split(Global.COMMA)));
|
|
|
|
|
- }
|
|
|
|
|
-// String withoutLinks = customConfig.getWithoutLinks();
|
|
|
|
|
-// if (StringUtils.isNotBlank(withoutLinks)) {
|
|
|
|
|
-// WITHOUTPATH.addAll(Arrays.asList(withoutLinks.split(Global.COMMA)));
|
|
|
|
|
-// }
|
|
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
|
|
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
|
|
|
FilterChain filterChain) throws IOException, ServletException {
|
|
FilterChain filterChain) throws IOException, ServletException {
|
|
|
HttpServletRequest request = (HttpServletRequest) servletRequest;
|
|
HttpServletRequest request = (HttpServletRequest) servletRequest;
|
|
|
- HttpServletResponse response = (HttpServletResponse) servletResponse;
|
|
|
|
|
- String token = request.getHeader(RequestConstant.TOKEN);
|
|
|
|
|
- String clientType = request.getHeader(RequestConstant.CLIENT_TYPE);
|
|
|
|
|
- Integer systemType = request.getIntHeader(RequestConstant.SYSTEM_TYPE);
|
|
|
|
|
-// String accessSpecial = request.getHeader(RequestConstant.ACCESS_SPECIAL);
|
|
|
|
|
- String requestUri = request.getRequestURI();
|
|
|
|
|
- /*1、非token校验接口放行*/
|
|
|
|
|
- if (EXCLUDEPATH.contains(requestUri)) {
|
|
|
|
|
- filterChain.doFilter(servletRequest, servletResponse);
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 添加对Swagger相关路径的放行
|
|
|
|
|
- if (requestUri.startsWith("/swagger-ui") ||
|
|
|
|
|
- requestUri.startsWith("/v3/api-docs") || requestUri.startsWith("/doc.htm")||
|
|
|
|
|
- requestUri.startsWith("/webjars/")) {
|
|
|
|
|
- filterChain.doFilter(servletRequest, servletResponse);
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /*2、校验token**/
|
|
|
|
|
- /*2.1、校验token非空*/
|
|
|
|
|
- HttpResult result = checkBlank(token, clientType, systemType, requestUri);
|
|
|
|
|
- if (result.getCode() != HttpStatus.SUCCESS_CODE) {
|
|
|
|
|
- ResponseUtil.writer(response, result);
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /*2.2、token解析*/
|
|
|
|
|
- Map<String, Object> tokenMap = EncryUtil.descryV2(Global.PRI_KEY, token);
|
|
|
|
|
- if (tokenMap == null) {
|
|
|
|
|
- ResponseUtil.writer(response, HttpResult.error(HttpStatus.TOKEN_INVALID_CODE, HttpStatus.TOKEN_INVALID_MESSAGE));
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /*2.3、从redis获取用户登录token*/
|
|
|
|
|
- Long userId = StringUtils.isNotBlank(tokenMap.get("userId")) ? NumberUtils.parseLong(tokenMap.get("userId")) : null;
|
|
|
|
|
- String key = Global.getFullUserTokenKey(clientType, userId);
|
|
|
|
|
- String redisUserToken = RedissonUtils.getString(key);
|
|
|
|
|
- if (StringUtils.isBlank(redisUserToken)) {
|
|
|
|
|
- ResponseUtil.writer(response, HttpResult.error(HttpStatus.TOKEN_INVALID_CODE, HttpStatus.TOKEN_INVALID_MESSAGE));
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /*2.4、请求token和redis中token不一致,说明账号在别处登录了*/
|
|
|
|
|
- if (!token.equals(redisUserToken)) {
|
|
|
|
|
- ResponseUtil.writer(response, HttpResult.error(HttpStatus.TOKEN_INVALID_CODE, HttpStatus.ACCOUNT_OTHER_LOGIN_MESSAGE));
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /*3、校验登录用户信息*/
|
|
|
|
|
- key = Global.getFullUserLoginKey(systemType, userId);
|
|
|
|
|
- String userInfoStr = RedissonUtils.getString(key);
|
|
|
|
|
- LoginUserInfo loginUserInfo = StringUtils.isNotBlank(userInfoStr) ? JSON.parseObject(userInfoStr, LoginUserInfo.class) : null;
|
|
|
|
|
- if (Objects.isNull(loginUserInfo)) {
|
|
|
|
|
- ResponseUtil.writer(response, HttpResult.error(HttpStatus.TOKEN_INVALID_CODE, HttpStatus.TOKEN_INVALID_MESSAGE));
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
- loginUserInfo.setClientType(clientType);
|
|
|
|
|
-
|
|
|
|
|
- //校验用户账号是否冻结
|
|
|
|
|
- if (loginUserInfo.getStatus() == Global.YES) {
|
|
|
|
|
- ResponseUtil.writer(response, HttpResult.error(HttpStatus.TOKEN_INVALID_CODE, "您的账号已被冻结,请联系系统管理员!"));
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /*4、登录中的企业信息*/
|
|
|
|
|
- String loginEntStr = RedissonUtils.getString(Global.getFullUserEntKey(loginUserInfo.getEntId()));
|
|
|
|
|
- LoginEntInfo loginEntInfo = StringUtils.isNotBlank(loginEntStr) ? JSON.parseObject(loginEntStr, LoginEntInfo.class) : null;
|
|
|
|
|
- if (SystemTypeEnum.MANAGE.getCode().equals(systemType)) {
|
|
|
|
|
- //redis 获取客户经理绑定企业ID
|
|
|
|
|
- String managerKey = Global.getCustomerManagerUserLoginKey(SystemTypeEnum.MANAGE.getCode(), loginUserInfo.getId());
|
|
|
|
|
- RSet<Object> set = RedissonUtils.getSet(managerKey);
|
|
|
|
|
- if (Objects.nonNull(set)) {
|
|
|
|
|
- List authUserIdList = JSONObject.parseObject(set.toString(), List.class);
|
|
|
|
|
- if (CollectionUtils.isNotEmpty(authUserIdList)) {
|
|
|
|
|
- loginUserInfo.setAuthEntIdList(authUserIdList);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- LoginUserHolder.set(loginUserInfo);
|
|
|
|
|
- LoginEntHolder.set(loginEntInfo);
|
|
|
|
|
- RedissonUtils.putString(Global.getFullUserTokenKey(clientType, userId), token, ClientTypeEnum.expireTime(clientType));
|
|
|
|
|
- RedissonUtils.putString(Global.getFullUserLoginKey(systemType, loginUserInfo.getId()), JSON.toJSONString(loginUserInfo), Global.APP_TOKEN_EXPIRE);
|
|
|
|
|
- RedissonUtils.putString(Global.getFullUserEntKey(loginEntInfo.getId()), JSON.toJSONString(loginEntInfo), Global.APP_TOKEN_EXPIRE);
|
|
|
|
|
- filterChain.doFilter(servletRequest, servletResponse);
|
|
|
|
|
- LoginUserHolder.remove();
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if ((StringUtils.isBlank(loginEntStr) || loginEntInfo == null) && !Objects.equals(systemType, SystemTypeEnum.MANAGE.getCode())) {
|
|
|
|
|
- ResponseUtil.writer(response, HttpResult.error(HttpStatus.TOKEN_INVALID_CODE, HttpStatus.UN_LOGIN_MESSAGE));
|
|
|
|
|
- return;
|
|
|
|
|
- } else {
|
|
|
|
|
- //校验用户企业是否冻结
|
|
|
|
|
- if (Objects.isNull(loginEntInfo) || loginEntInfo.getStatus() == Global.YES) {
|
|
|
|
|
- ResponseUtil.writer(response, HttpResult.error(HttpStatus.TOKEN_INVALID_CODE, "您所属企业已被冻结,请联系系统管理员!"));
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- //校验用户企业审批状态
|
|
|
|
|
- if (!loginEntInfo.getValid() && !REGISTER.equals(requestUri)) {
|
|
|
|
|
- if (loginEntInfo.getApproval() == Global.NO) {
|
|
|
|
|
- ResponseUtil.writer(response, HttpResult.error(HttpStatus.CODE_60603, HttpStatus.ENTCERTIFICATES_NOT_REGISTER));
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (loginEntInfo.getApproval() == Global.NUMERICAL_THREE) {
|
|
|
|
|
- ResponseUtil.writer(response, HttpResult.error(HttpStatus.CODE_60603, HttpStatus.ENTCERTIFICATES_NOT_PASS));
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- ResponseUtil.writer(response, HttpResult.error(HttpStatus.CODE_60603, HttpStatus.ENTCERTIFICATES_INVAILD));
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /*5、请求权限校验*/
|
|
|
|
|
- //非管理员有接口权限才放行
|
|
|
|
|
- if (loginUserInfo.getIsMain() == Global.NO
|
|
|
|
|
- && !WITHOUTPATH.contains(requestUri)
|
|
|
|
|
- && !checkMenu(clientType, loginUserInfo.getId(), requestUri)) {
|
|
|
|
|
- ResponseUtil.writer(response, HttpResult.error(HttpStatus.AUTHORITY_NO_CODE, HttpStatus.ACCESS_FIAL));
|
|
|
|
|
- return;
|
|
|
|
|
|
|
+ String userInfoStrEncode = request.getHeader(Global.USER_INFO_STR_ENCODE);
|
|
|
|
|
+ String entInfoStrEncode = request.getHeader(Global.ENT_INFO_STR_ENCODE);
|
|
|
|
|
+ LoginUserInfo loginUserInfo = null;
|
|
|
|
|
+ LoginEntInfo loginEntInfo = null;
|
|
|
|
|
+ if(StringUtils.isNotBlank(userInfoStrEncode)){
|
|
|
|
|
+ String userInfoStr = URLDecoder.decode(userInfoStrEncode, StandardCharsets.UTF_8);
|
|
|
|
|
+ loginUserInfo = JSON.parseObject(userInfoStr, LoginUserInfo.class);
|
|
|
|
|
+ }
|
|
|
|
|
+ if(StringUtils.isNotBlank(entInfoStrEncode)){
|
|
|
|
|
+ String entInfoStr = URLDecoder.decode(entInfoStrEncode, StandardCharsets.UTF_8);
|
|
|
|
|
+ loginEntInfo = JSON.parseObject(entInfoStr, LoginEntInfo.class);
|
|
|
}
|
|
}
|
|
|
LoginUserHolder.set(loginUserInfo);
|
|
LoginUserHolder.set(loginUserInfo);
|
|
|
LoginEntHolder.set(loginEntInfo);
|
|
LoginEntHolder.set(loginEntInfo);
|
|
|
- RedissonUtils.putString(Global.getFullUserLoginKey(systemType, loginUserInfo.getId()), JSON.toJSONString(loginUserInfo), Global.APP_TOKEN_EXPIRE);
|
|
|
|
|
- RedissonUtils.putString(Global.getFullUserEntKey(loginEntInfo.getId()), JSON.toJSONString(loginEntInfo), Global.APP_TOKEN_EXPIRE);
|
|
|
|
|
- RedissonUtils.putString(Global.getFullUserTokenKey(clientType, userId), token, ClientTypeEnum.expireTime(clientType));
|
|
|
|
|
filterChain.doFilter(servletRequest, servletResponse);
|
|
filterChain.doFilter(servletRequest, servletResponse);
|
|
|
LoginUserHolder.remove();
|
|
LoginUserHolder.remove();
|
|
|
LoginEntHolder.remove();
|
|
LoginEntHolder.remove();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * @param userId 用户菜单权限key url 当前请求url
|
|
|
|
|
- * @return boolean
|
|
|
|
|
- * @desc: 校验url权限
|
|
|
|
|
- * @author: czh
|
|
|
|
|
- * @date: 2023/6/28
|
|
|
|
|
- */
|
|
|
|
|
- private boolean checkMenu(String clientType, Long userId, String url) {
|
|
|
|
|
- return true;
|
|
|
|
|
- //return RedissonUtils.contains(Global.REDIS_SYS_MENU_PREFIX + clientType + Global.COLON + userId, url);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * @param token token
|
|
|
|
|
- * @param clientType 客户端类型
|
|
|
|
|
- * @param systemType 系统类型
|
|
|
|
|
- * @param accessSpecial 专场标识
|
|
|
|
|
- * @param requestUri 请求地址
|
|
|
|
|
- * @return 校验结果
|
|
|
|
|
- * @desc Hearder内容校验
|
|
|
|
|
- * @author zk
|
|
|
|
|
- * @date 2023/12/14
|
|
|
|
|
- **/
|
|
|
|
|
- private HttpResult checkBlank(String token, String clientType, Integer systemType, String requestUri) {
|
|
|
|
|
- if (StringUtils.isBlank(token)) {
|
|
|
|
|
- return HttpResult.error(HttpStatus.PARAMETERS_MISSING_CODE, HttpStatus.UN_LOGIN_MESSAGE);
|
|
|
|
|
- }
|
|
|
|
|
- if (StringUtils.isBlank(clientType)) {
|
|
|
|
|
- return HttpResult.error(HttpStatus.PARAMETERS_MISSING_CODE, HttpStatus.INVALID_REQUEST);
|
|
|
|
|
- }
|
|
|
|
|
- if (StringUtils.isBlank(systemType)) {
|
|
|
|
|
- return HttpResult.error(HttpStatus.PARAMETERS_MISSING_CODE, HttpStatus.INVALID_REQUEST);
|
|
|
|
|
- }
|
|
|
|
|
- return HttpResult.ok();
|
|
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public int getOrder() {
|
|
|
|
|
+ return -1;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
}
|
|
}
|