ludc
2025-01-16 5203081b68e3a8dc139d1807b2f8774e4a00a82a
Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/interceptor/VciSecurityInterceptor.java
@@ -4,9 +4,12 @@
import com.vci.starter.web.annotation.controller.VciUnCheckRight;
import com.vci.starter.web.autoconfigure.SpringMVCConfig;
import com.vci.starter.web.constant.TokenKeyConstant;
import com.vci.starter.web.constant.VConstant;
import com.vci.starter.web.enumpck.ResultCodeEnum;
import com.vci.starter.web.pagemodel.BaseResult;
import com.vci.starter.web.pagemodel.SessionInfo;
import com.vci.starter.web.redis.RedisService;
import com.vci.starter.web.util.ApplicationContextProvider;
import com.vci.starter.web.util.LangBaseUtil;
import com.vci.starter.web.util.VciBaseUtil;
import com.vci.starter.web.util.WebThreadLocalUtil;
@@ -14,6 +17,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.CollectionUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
@@ -30,6 +34,7 @@
 * @author weidy
 * @date 2019/11/7 2:32 PM
 */
//@Configuration
public class VciSecurityInterceptor implements HandlerInterceptor {
    /**
@@ -46,8 +51,11 @@
    /**
     * 会话,权限,token的接口
     */
    @Autowired(required = false)
    private VciSessionForLoginI sessionForLoginI;
    @Autowired
    private VciSessionForLoginI vciSessionForLoginI;
    @Autowired
    private RedisService redisService;
    /**
     * 执行拦截
@@ -69,39 +77,40 @@
        if(StringUtils.isBlank(userToken)){
            userToken = request.getParameter(TokenKeyConstant.USER_TOKEN_KEY);
        }
        if(!(handler instanceof  HandlerMethod)){
        if(!(handler instanceof HandlerMethod)){
            return true;
        }
        List<String> unCheckUrls = new ArrayList<>();
        if(springMVCConfig !=null && springMVCConfig.getUnCheckUrls() !=null){
            unCheckUrls = springMVCConfig.getUnCheckUrls();
        }
        SessionInfo sessionInfo = null;
        if(StringUtils.isNotBlank(userToken)){
            try{
                sessionInfo = sessionForLoginI.getSessionInfoByToken(userToken);
            }catch (Throwable e){
                logger.error("获取token出错",e);
                //sendErrorMsg(response,"获取token的信息出错," + userToken + "," + LangBaseUtil.getErrorMsg(e),1);
                //return false;
            }
            if(sessionInfo!=null){
                WebThreadLocalUtil.getCurrentUserSessionInfoInThread().set(sessionInfo);
            }
        }
        boolean unCheckLogin = false;
        if(handler instanceof  HandlerMethod) {
            HandlerMethod hm = (HandlerMethod)handler;
            Method method = hm.getMethod();
            //设置了不校验的会直接返回true
            if (method.isAnnotationPresent(VciUnCheckRight.class)) {
                return true;
                unCheckLogin = true;
            }
            if (method.getDeclaringClass().isAnnotationPresent(VciUnCheckRight.class)) {
                return true;
                unCheckLogin = true;
            }
        }
        if(url.endsWith(".md")){
            unCheckLogin = true;
        }
        if(unCheckLogin){
            //虽然不校验权限,但是如果token不为空,需要更新当前用户
            SessionInfo sessionInfo = getSessionInfo(userToken);
            if(sessionInfo != null){
                //初始化平台的token
                vciSessionForLoginI.initInvocationInfo(sessionInfo);
            }
            return true;
        }
        //获取配置文件中,不校验权限的路径
        List<String> unCheckUrls = new ArrayList<>();
        if(springMVCConfig !=null && springMVCConfig.getUnCheckUrls() !=null){
            unCheckUrls = springMVCConfig.getUnCheckUrls();
        }
        if(StringUtils.isBlank(userToken) && !unCheckUrls.contains(url)){
            //说明是没有用户信息的,而且也必须要校验是否登录的情况
@@ -111,18 +120,24 @@
            }
            sendErrorMsg(response,"没有登录系统,请先登录",1);
            return false;
            //被T下线由websocket直接提醒
            //被踢下线由websocket直接提醒
        }else{
            SessionInfo sessionInfo = getSessionInfo(userToken);
            if(sessionInfo == null){
                //也是说明不存在,被T下线时也获取不到session的信息了
                //也是说明不存在,被踢下线时也获取不到session的信息了
                if(logger.isErrorEnabled()) {
                    logger.error("token值非法,或者用户已经被踢下线," + userToken);
                    logger.error("token值非法,或过期,或者用户已经被踢下线," + userToken);
                }
                sendErrorMsg(response,"token值非法,或者用户已经被踢下线," + userToken,1);
                //删除缓存中统计的用户信息
                if(redisService == null){
                    redisService = ApplicationContextProvider.getBean(RedisService.class);
                }
                redisService.decreOnlineUser(VConstant.CURRENT_LOGGED_USERS_KEY);
                sendErrorMsg(response,"token值非法,或过期,或者用户已经被踢下线," + userToken,1);
                return false;
            }else{
                if(!unCheckUrls.contains(url)){
                    if(sessionForLoginI == null){
                    if(vciSessionForLoginI == null){
                        //说明没办法校验
                        String msg = "请求路径"+ url +"没权限访问";
                        if(logger.isErrorEnabled()) {
@@ -131,9 +146,12 @@
                        sendErrorMsg(response,msg,2);
                        return false;
                    }else{
                        //初始化平台的token
                        vciSessionForLoginI.initInvocationInfo(sessionInfo);
                        String systemPrivateToken = request.getHeader(TokenKeyConstant.SYSTEM_PRIVATE_KEY);
                        try {
                            if (sessionForLoginI.checkRequestRights(request, systemPrivateToken, sessionInfo, handler)) {
                            if (vciSessionForLoginI.checkRequestRights(request, systemPrivateToken, sessionInfo, handler)) {
                                updateRequestTime(url,userToken);
                            }else{
                                return false;
@@ -153,6 +171,26 @@
            }
        }
        return true;
    }
    private SessionInfo getSessionInfo(String userToken){
        SessionInfo sessionInfo = null;
        if(StringUtils.isNotBlank(userToken)){
            try{
                if(vciSessionForLoginI == null){
                    vciSessionForLoginI = ApplicationContextProvider.getBean(VciSessionForLoginI.class);
                }
                sessionInfo = vciSessionForLoginI.getSessionInfoByToken(userToken);
            }catch (Throwable e){
                logger.error("获取token出错",e);
            }
            if(sessionInfo!=null){
                WebThreadLocalUtil.setCurrentUserSessionInfoInThread(sessionInfo);
                WebThreadLocalUtil.setTokenInThread(TokenKeyConstant.TOKEN_KEY_PREFIX_IN_REDIS+sessionInfo.getToken());
            }
        }
        return sessionInfo;
    }
    /**
@@ -191,8 +229,8 @@
        while(url1.startsWith("/")){
            url1 = url1.substring(1);
        }
        if(sessionForLoginI != null && !unStorageRequestTimeUrls.contains(url1)){
            sessionForLoginI.updateRequestTime(userToken);
        if(vciSessionForLoginI != null && !unStorageRequestTimeUrls.contains(url1)){
            vciSessionForLoginI.updateRequestTime(userToken);
        }
    }
}