Browse Source

feat: 优化当前登陆人信息

huangzqa 1 year ago
parent
commit
2967bad8d2
21 changed files with 816 additions and 209 deletions
  1. 6 0
      approve-core-service/pom.xml
  2. 53 0
      approve-core-service/src/main/java/com/dragonsoft/dcuc/approve/business/ISecurityUserBusiness.java
  3. 41 38
      approve-core-service/src/main/java/com/dragonsoft/dcuc/approve/business/external/impl/BuSyncBusinessImpl.java
  4. 8 8
      approve-core-service/src/main/java/com/dragonsoft/dcuc/approve/business/external/impl/DcucAuthBusinessImpl.java
  5. 20 14
      approve-core-service/src/main/java/com/dragonsoft/dcuc/approve/business/external/impl/DcucBusinessImpl.java
  6. 150 0
      approve-core-service/src/main/java/com/dragonsoft/dcuc/approve/business/impl/SecurityUserBusinessImpl.java
  7. 0 19
      approve-core-service/src/main/java/com/dragonsoft/dcuc/approve/config/ApproveConfig.java
  8. 47 0
      approve-core-service/src/main/java/com/dragonsoft/dcuc/approve/config/ProofConfiguration.java
  9. 7 8
      approve-core-service/src/main/java/com/dragonsoft/dcuc/approve/facade/api/ApiV1ApproveFacade.java
  10. 46 37
      approve-core-service/src/main/java/com/dragonsoft/dcuc/approve/facade/api/ApiV2ApproveFacade.java
  11. 35 40
      approve-core-service/src/main/java/com/dragonsoft/dcuc/approve/facade/api/v3/ApiV3ApproveFacade.java
  12. 27 9
      approve-core-service/src/main/java/com/dragonsoft/dcuc/approve/filter/CheckProofsFilter.java
  13. 25 0
      approve-core-service/src/main/java/com/dragonsoft/dcuc/approve/filter/cache/ISecurityAppResolver.java
  14. 25 0
      approve-core-service/src/main/java/com/dragonsoft/dcuc/approve/filter/cache/ISecurityUserResolver.java
  15. 50 0
      approve-core-service/src/main/java/com/dragonsoft/dcuc/approve/filter/cache/SecurityAppCache.java
  16. 43 0
      approve-core-service/src/main/java/com/dragonsoft/dcuc/approve/filter/cache/SecurityAppResolver.java
  17. 50 0
      approve-core-service/src/main/java/com/dragonsoft/dcuc/approve/filter/cache/SecurityUserCache.java
  18. 50 0
      approve-core-service/src/main/java/com/dragonsoft/dcuc/approve/filter/cache/SecurityUserResolver.java
  19. 74 0
      approve-core-service/src/main/java/com/dragonsoft/dcuc/approve/properties/ProofStarterProperties.java
  20. 0 31
      approve-core-service/src/main/java/com/dragonsoft/dcuc/approve/threadlocal/ThreadLocalProofsHolder.java
  21. 59 5
      approve-core-service/src/main/java/com/dragonsoft/dcuc/approve/utils/ProofsUtil.java

+ 6 - 0
approve-core-service/pom.xml

@@ -43,6 +43,12 @@
         <dependency>
             <groupId>com.dragoninfo</groupId>
             <artifactId>dcuc-duceap-api</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>com.dragonsoft.dyy</groupId>
+                    <artifactId>nosql-elasticsearch-api</artifactId>
+                </exclusion>
+            </exclusions>
         </dependency>
         <dependency>
             <groupId>com.dragonsoft</groupId>

+ 53 - 0
approve-core-service/src/main/java/com/dragonsoft/dcuc/approve/business/ISecurityUserBusiness.java

@@ -0,0 +1,53 @@
+package com.dragonsoft.dcuc.approve.business;
+
+import com.dragoninfo.dcuc.common.entity.SecurityApp;
+import com.dragonsoft.dcuc.approve.model.resp.bim.ZeroTrustAppTokenInfoRespVO;
+import com.dragonsoft.duceap.base.entity.http.ResponseDTO;
+import com.dragonsoft.duceap.base.entity.security.SecurityUser;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * <p>
+ *
+ * </p>
+ *
+ * @author huangzqa
+ * @date 2023/11/15
+ */
+public interface ISecurityUserBusiness {
+
+    /**
+     * 获取应用信息
+     *
+     * @param appCode 应用代码
+     * @return 应用信息
+     */
+    SecurityApp getSecurityApp(String appCode);
+
+    /**
+     * 获取当前登陆人信息
+     *
+     * @param idcard  身份证号
+     * @param appCode 应用代码
+     * @return 当前用户
+     */
+    ResponseDTO<SecurityUser> getSecurityUser(String idcard, String appCode);
+
+    /**
+     * 设置用户额外信息
+     *
+     * @param securityUser 当前登陆人
+     * @param request      请求
+     */
+    void setUserExtInfo(SecurityUser securityUser, HttpServletRequest request);
+
+    /**
+     * 设置用户额外信息
+     *
+     * @param securityUser 当前登陆人
+     * @param appTokenInfo 应用令牌信息
+     */
+    void setUserExtInfo(SecurityUser securityUser, ZeroTrustAppTokenInfoRespVO appTokenInfo);
+
+}

+ 41 - 38
approve-core-service/src/main/java/com/dragonsoft/dcuc/approve/business/external/impl/BuSyncBusinessImpl.java

@@ -7,13 +7,13 @@ import com.dragonsoft.dcuc.approve.business.INoticeBusiness;
 import com.dragonsoft.dcuc.approve.business.api.IApproveApiBusiness;
 import com.dragonsoft.dcuc.approve.business.external.IBuSyncBusiness;
 import com.dragonsoft.dcuc.approve.enumresources.bu.ApproveModeEnum;
-import com.dragonsoft.dcuc.approve.model.dto.ApprovalInfoDTO;
 import com.dragonsoft.dcuc.approve.model.ApproveCirculationInfo;
 import com.dragonsoft.dcuc.approve.model.ApproveRecordInfo;
+import com.dragonsoft.dcuc.approve.model.dto.ApprovalInfoDTO;
+import com.dragonsoft.dcuc.approve.model.dto.ApproveMessageInfoDTO;
 import com.dragonsoft.dcuc.approve.model.resp.bu.BuApproveSyncBizApproveReqVO;
 import com.dragonsoft.dcuc.approve.model.resp.bu.BuApproveSyncBizDataReqVO;
 import com.dragonsoft.dcuc.approve.model.resp.bu.BuApproveSyncReqVO;
-import com.dragonsoft.dcuc.approve.model.dto.ApproveMessageInfoDTO;
 import com.dragonsoft.dcuc.approve.service.IApproveCirculationService;
 import com.dragonsoft.dcuc.approve.service.IApproveRecordService;
 import com.dragonsoft.duceap.base.entity.http.ResponseStatus;
@@ -104,15 +104,11 @@ public class BuSyncBusinessImpl implements IBuSyncBusiness {
     @Override
     public ResponseStatus syncToBu(ApproveRecordInfo approveRecordInfo) {
         Assert.notNull(approveRecordInfo);
+        ApprovalInfoDTO approvalInfoDTO = approveRecordInfo.toApprovalInfo();
 
         String id = approveRecordInfo.getId();
 
         BuApproveSyncReqVO buApproveSyncReqVO = new BuApproveSyncReqVO();
-        buApproveSyncReqVO.setAppId(approveRecordInfo.getAppCode());
-        buApproveSyncReqVO.setAppName(approveRecordInfo.getAppName());
-        buApproveSyncReqVO.setCreateTime(approveRecordInfo.getCreateTime());
-        buApproveSyncReqVO.setFinishTime(approveRecordInfo.getUpdateTime());
-        buApproveSyncReqVO.setPid(approveRecordInfo.getApplicantIdcard());
 
         ApproveCirculationInfo approveCirculationInfo = approveCirculationService.getListByApproveRecordLastAgree(id);
         Assert.notNull(approveCirculationInfo);
@@ -122,25 +118,7 @@ public class BuSyncBusinessImpl implements IBuSyncBusiness {
         buApproveSyncReqVO.setLastReviewerUnitCode(approveCirculationInfo.getOperateUserOrgId());
         buApproveSyncReqVO.setLastReviewerUnit(approveCirculationInfo.getOperateUserOrg());
 
-        BuApproveSyncBizApproveReqVO buApproveSyncBizApproveReqVO = new BuApproveSyncBizApproveReqVO();
-        buApproveSyncBizApproveReqVO.setBizId(approveRecordInfo.getApproveNo());
-        buApproveSyncBizApproveReqVO.setBizTitle(approveRecordInfo.getProcessTitle());
-        buApproveSyncBizApproveReqVO.setTaskClass(approveRecordInfo.getApproveTaskClass());
-        buApproveSyncBizApproveReqVO.setApproveMode(ApproveModeEnum.NORMAL.value);
-        buApproveSyncBizApproveReqVO.setBizTermStart(approveRecordInfo.getStartTime());
-        buApproveSyncBizApproveReqVO.setBizTermEnd(approveRecordInfo.getEndTime());
-
-        BuApproveSyncBizDataReqVO buApproveSyncBizDataReqVO = new BuApproveSyncBizDataReqVO();
-        buApproveSyncBizDataReqVO.setBizApprove(buApproveSyncBizApproveReqVO);
-        buApproveSyncReqVO.setBizData(buApproveSyncBizDataReqVO);
-
-        ResponseStatus responseStatus = noticeBusiness.retryRequestSyncToBu(buApproveSyncReqVO);
-        if (ResponseUtil.isSuccess(responseStatus)) {
-            approveRecordService.updateSyncFlag(id, BooleanEnum.TRUE);
-            return ResponseStatus.success();
-        }
-        approveRecordService.updateSyncFlag(id, BooleanEnum.FALSE);
-        return ResponseStatus.fail();
+        return syncToBu(id, buApproveSyncReqVO, approvalInfoDTO);
     }
 
     @Transactional(rollbackFor = Throwable.class)
@@ -150,11 +128,6 @@ public class BuSyncBusinessImpl implements IBuSyncBusiness {
         String id = approvalInfoDTO.getId();
 
         BuApproveSyncReqVO buApproveSyncReqVO = new BuApproveSyncReqVO();
-        buApproveSyncReqVO.setAppId(approvalInfoDTO.getAppCode());
-        buApproveSyncReqVO.setAppName(approvalInfoDTO.getAppName());
-        buApproveSyncReqVO.setCreateTime(approvalInfoDTO.getCreateTime());
-        buApproveSyncReqVO.setFinishTime(approvalInfoDTO.getUpdateTime());
-        buApproveSyncReqVO.setPid(approvalInfoDTO.getApplicantIdcard());
 
         SecurityUser securityUser = approveMessageInfoDTO.getSecurityUser();
 
@@ -165,18 +138,31 @@ public class BuSyncBusinessImpl implements IBuSyncBusiness {
         buApproveSyncReqVO.setLastReviewerUnitCode(securityUser.getSecurityOrg());
         buApproveSyncReqVO.setLastReviewerUnit(securityUser.getSecurityOrgName());
 
-        BuApproveSyncBizApproveReqVO buApproveSyncBizApproveReqVO = new BuApproveSyncBizApproveReqVO();
-        buApproveSyncBizApproveReqVO.setBizId(approvalInfoDTO.getApproveNo());
-        buApproveSyncBizApproveReqVO.setBizTitle(approvalInfoDTO.getProcessTitle());
-        buApproveSyncBizApproveReqVO.setTaskClass(approvalInfoDTO.getApproveTaskClass());
-        buApproveSyncBizApproveReqVO.setApproveMode(ApproveModeEnum.NORMAL.value);
-        buApproveSyncBizApproveReqVO.setBizTermStart(approvalInfoDTO.getStartTime());
-        buApproveSyncBizApproveReqVO.setBizTermEnd(approvalInfoDTO.getEndTime());
+        return syncToBu(id, buApproveSyncReqVO, approvalInfoDTO);
+    }
+
+    /**
+     * 同步到 BU
+     *
+     * @param id                 审批单ID
+     * @param buApproveSyncReqVO 请求
+     * @param approvalInfoDTO    审批单信息
+     * @return 状态
+     */
+    protected ResponseStatus syncToBu(String id, BuApproveSyncReqVO buApproveSyncReqVO, ApprovalInfoDTO approvalInfoDTO) {
+        buApproveSyncReqVO.setAppId(approvalInfoDTO.getAppCode());
+        buApproveSyncReqVO.setAppName(approvalInfoDTO.getAppName());
+        buApproveSyncReqVO.setCreateTime(approvalInfoDTO.getCreateTime());
+        buApproveSyncReqVO.setFinishTime(approvalInfoDTO.getUpdateTime());
+        buApproveSyncReqVO.setPid(approvalInfoDTO.getApplicantIdcard());
+
+        BuApproveSyncBizApproveReqVO buApproveSyncBizApproveReqVO = parseApprovalInfoDTO(approvalInfoDTO);
 
         BuApproveSyncBizDataReqVO buApproveSyncBizDataReqVO = new BuApproveSyncBizDataReqVO();
         buApproveSyncBizDataReqVO.setBizApprove(buApproveSyncBizApproveReqVO);
         buApproveSyncReqVO.setBizData(buApproveSyncBizDataReqVO);
 
+
         ResponseStatus responseStatus = noticeBusiness.retryRequestSyncToBu(buApproveSyncReqVO);
         if (ResponseUtil.isSuccess(responseStatus)) {
             approveRecordService.updateSyncFlag(id, BooleanEnum.TRUE);
@@ -186,5 +172,22 @@ public class BuSyncBusinessImpl implements IBuSyncBusiness {
         return ResponseStatus.fail();
     }
 
+    /**
+     * 转换
+     *
+     * @param approvalInfoDTO 审批单信息
+     * @return 流程业务数据
+     */
+    protected BuApproveSyncBizApproveReqVO parseApprovalInfoDTO(ApprovalInfoDTO approvalInfoDTO) {
+        BuApproveSyncBizApproveReqVO buApproveSyncBizApproveReqVO = new BuApproveSyncBizApproveReqVO();
+        buApproveSyncBizApproveReqVO.setBizId(approvalInfoDTO.getApproveNo());
+        buApproveSyncBizApproveReqVO.setBizTitle(approvalInfoDTO.getProcessTitle());
+        buApproveSyncBizApproveReqVO.setTaskClass(approvalInfoDTO.getApproveTaskClass());
+        buApproveSyncBizApproveReqVO.setApproveMode(ApproveModeEnum.NORMAL.value);
+        buApproveSyncBizApproveReqVO.setBizTermStart(approvalInfoDTO.getStartTime());
+        buApproveSyncBizApproveReqVO.setBizTermEnd(approvalInfoDTO.getEndTime());
+        return buApproveSyncBizApproveReqVO;
+    }
+
 
 }

+ 8 - 8
approve-core-service/src/main/java/com/dragonsoft/dcuc/approve/business/external/impl/DcucAuthBusinessImpl.java

@@ -5,17 +5,18 @@ import com.dragoninfo.dcuc.common.entity.*;
 import com.dragonsoft.auditlog.collection.qmtj.provider.IRestTemplateProvider;
 import com.dragonsoft.dcuc.approve.business.external.IDcucAuthBusiness;
 import com.dragonsoft.dcuc.approve.constants.ApproveConstants;
-import com.dragonsoft.dcuc.approve.model.dto.ResourceInfoDTO;
 import com.dragonsoft.dcuc.approve.enumresources.FlowTypeEnum;
 import com.dragonsoft.dcuc.approve.enumresources.ListLevelEnum;
 import com.dragonsoft.dcuc.approve.enumresources.ListResourceTypeEnum;
+import com.dragonsoft.dcuc.approve.model.dto.ResourceInfoDTO;
 import com.dragonsoft.dcuc.approve.model.req.AppFunctionResourceReqVO;
 import com.dragonsoft.dcuc.approve.model.resp.OperateRespVO;
 import com.dragonsoft.dcuc.approve.model.vo.AppFunRedListVo;
 import com.dragonsoft.dcuc.approve.model.vo.AuthAppFunApiVO;
 import com.dragonsoft.dcuc.approve.model.vo.WhiteListUserApiVo;
 import com.dragonsoft.dcuc.approve.properties.ApproveProperties;
-import com.dragonsoft.dcuc.approve.threadlocal.ThreadLocalProofsHolder;
+
+import com.dragonsoft.dcuc.approve.utils.ProofsUtil;
 import com.dragonsoft.duceap.base.entity.http.ResponseStatus;
 import com.dragonsoft.duceap.commons.util.json.JsonUtils;
 import com.dragonsoft.duceap.core.search.enums.SearchOperator;
@@ -111,8 +112,7 @@ public class DcucAuthBusinessImpl implements IDcucAuthBusiness {
 
     @SneakyThrows(JsonProcessingException.class)
     private Set<ListLevelEnum> getFunctionLevel(String appCode, List<String> functionCodeArray) {
-        Proofs proofs = ThreadLocalProofsHolder.getProofs();
-        HttpHeaders httpHeaders = proofs.buildHttpHeaders();
+        HttpHeaders httpHeaders = ProofsUtil.buildHttpHeaders();
         log.debug("header:{}", httpHeaders);
 
         Map<String, SearchParam> filters = new HashMap<>(1);
@@ -164,8 +164,8 @@ public class DcucAuthBusinessImpl implements IDcucAuthBusiness {
     @Override
     @SneakyThrows(JsonProcessingException.class)
     public List<AuthAppFunApiVO> getFunctionList(String appCode, List<String> functionCodList) {
-        Proofs proofs = ThreadLocalProofsHolder.getProofs();
-        HttpHeaders httpHeaders = proofs.buildHttpHeaders();
+        
+        HttpHeaders httpHeaders = ProofsUtil.buildHttpHeaders();
         log.debug("header:{}", httpHeaders);
 
         Map<String, SearchParam> filters = new HashMap<>(1);
@@ -223,8 +223,8 @@ public class DcucAuthBusinessImpl implements IDcucAuthBusiness {
     @Override
     @SneakyThrows(JsonProcessingException.class)
     public Optional<ListLevelEnum> getWhiteListLevel(String resourceCode) {
-        Proofs proofs = ThreadLocalProofsHolder.getProofs();
-        HttpHeaders httpHeaders = proofs.buildHttpHeaders();
+        
+        HttpHeaders httpHeaders = ProofsUtil.buildHttpHeaders();
         log.debug("header:{}", httpHeaders);
 
         Map<String, SearchParam> filters = new HashMap<>(1);

+ 20 - 14
approve-core-service/src/main/java/com/dragonsoft/dcuc/approve/business/external/impl/DcucBusinessImpl.java

@@ -7,7 +7,6 @@ import com.alibaba.fastjson.JSONObject;
 import com.dragoninfo.dcuc.common.entity.ApiResult;
 import com.dragoninfo.dcuc.common.entity.ApiResultPage;
 import com.dragoninfo.dcuc.common.entity.ApiSearchReq;
-import com.dragoninfo.dcuc.common.entity.Proofs;
 import com.dragoninfo.dcuc.common.utils.ResponseUtil;
 import com.dragonsoft.dcuc.approve.business.external.IDcucBusiness;
 import com.dragonsoft.dcuc.approve.constants.ApproveBeanConstants;
@@ -15,9 +14,11 @@ import com.dragonsoft.dcuc.approve.model.vo.dcuc.ApiOrgResultVo;
 import com.dragonsoft.dcuc.approve.model.vo.dcuc.ApiPoliceResultVo;
 import com.dragonsoft.dcuc.approve.model.vo.dcuc.OauthUserVO;
 import com.dragonsoft.dcuc.approve.properties.ApproveProperties;
-import com.dragonsoft.dcuc.approve.threadlocal.ThreadLocalProofsHolder;
+import com.dragonsoft.dcuc.approve.utils.ProofsUtil;
 import com.dragonsoft.duceap.base.entity.http.ResponseDTO;
 import com.dragonsoft.duceap.base.entity.http.ResponseStatus;
+import com.dragonsoft.duceap.base.entity.security.SecurityUser;
+import com.dragonsoft.duceap.base.utils.UserContextUtils;
 import com.dragonsoft.duceap.commons.util.json.JsonUtils;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.core.type.TypeReference;
@@ -82,10 +83,12 @@ public class DcucBusinessImpl implements IDcucBusiness {
     public OauthUserVO getOauthUserInfoByIdcard(String searchIdcard) {
         Assert.notBlank(searchIdcard);
         //构建请求头
-        Proofs proofs = ThreadLocalProofsHolder.getProofs();
+
         HttpEntity<Map<String, Object>> requestEntity;
-        if (ObjectUtil.isNotNull(proofs)) {
-            HttpHeaders headers = proofs.buildHttpHeaders();
+        
+        SecurityUser currentUser = UserContextUtils.getCurrentUser();
+        if (ObjectUtil.isNotNull(currentUser)) {
+            HttpHeaders headers = ProofsUtil.buildHttpHeaders(currentUser);
             requestEntity = new HttpEntity<>(headers);
         } else {
             requestEntity = new HttpEntity<>(Collections.emptyMap());
@@ -113,10 +116,11 @@ public class DcucBusinessImpl implements IDcucBusiness {
     @Override
     public ApiOrgResultVo orgInfo(String orgCode) {
         //构建请求头
-        Proofs proofs = ThreadLocalProofsHolder.getProofs();
+        
         HttpEntity<Map<String, Object>> requestEntity;
-        if (ObjectUtil.isNotNull(proofs)) {
-            HttpHeaders headers = proofs.buildHttpHeaders();
+        SecurityUser currentUser = UserContextUtils.getCurrentUser();
+        if (ObjectUtil.isNotNull(currentUser)) {
+            HttpHeaders headers = ProofsUtil.buildHttpHeaders(currentUser);
             requestEntity = new HttpEntity<>(headers);
         } else {
             requestEntity = new HttpEntity<>(Collections.emptyMap());
@@ -148,10 +152,11 @@ public class DcucBusinessImpl implements IDcucBusiness {
 
         String userServiceUrl = approveProperties.getUserServiceUrl();
         String url = userServiceUrl + ORG_SYNC_API;
-        Proofs proofs = ThreadLocalProofsHolder.getProofs();
+        
         HttpHeaders httpHeaders = HttpHeaders.EMPTY;
-        if (ObjectUtil.isNotNull(proofs)) {
-            httpHeaders = proofs.buildHttpHeaders();
+        SecurityUser currentUser = UserContextUtils.getCurrentUser();
+        if (ObjectUtil.isNotNull(currentUser)) {
+            httpHeaders = ProofsUtil.buildHttpHeaders(currentUser);
         }
 
         RequestEntity<ApiSearchReq> apiSearchReqRequestEntity = new RequestEntity<>(apiSearchReq, httpHeaders, HttpMethod.POST, URI.create(url));
@@ -190,10 +195,11 @@ public class DcucBusinessImpl implements IDcucBusiness {
 
         String userServiceUrl = approveProperties.getUserServiceUrl();
         String url = userServiceUrl + POLICE_SYNC_API;
-        Proofs proofs = ThreadLocalProofsHolder.getProofs();
+
         HttpHeaders httpHeaders = HttpHeaders.EMPTY;
-        if (ObjectUtil.isNotNull(proofs)) {
-            httpHeaders = proofs.buildHttpHeaders();
+        SecurityUser currentUser = UserContextUtils.getCurrentUser();
+        if (ObjectUtil.isNotNull(currentUser)) {
+            httpHeaders = ProofsUtil.buildHttpHeaders(currentUser);
         }
 
         RequestEntity<ApiSearchReq> apiSearchReqRequestEntity = new RequestEntity<>(apiSearchReq, httpHeaders, HttpMethod.POST, URI.create(url));

+ 150 - 0
approve-core-service/src/main/java/com/dragonsoft/dcuc/approve/business/impl/SecurityUserBusinessImpl.java

@@ -0,0 +1,150 @@
+package com.dragonsoft.dcuc.approve.business.impl;
+
+import cn.hutool.core.map.MapUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.dragoninfo.dcuc.common.entity.SecurityApp;
+import com.dragoninfo.dcuc.common.enums.UserExtInfoEnum;
+import com.dragoninfo.dcuc.common.utils.ResponseUtil;
+import com.dragonsoft.dcuc.approve.business.ISecurityUserBusiness;
+import com.dragonsoft.dcuc.approve.filter.cache.ISecurityAppResolver;
+import com.dragonsoft.dcuc.approve.filter.cache.ISecurityUserResolver;
+import com.dragonsoft.dcuc.approve.filter.cache.SecurityAppCache;
+import com.dragonsoft.dcuc.approve.filter.cache.SecurityUserCache;
+import com.dragonsoft.dcuc.approve.model.resp.bim.ZeroTrustAppItemUserTokenInfoRespVO;
+import com.dragonsoft.dcuc.approve.model.resp.bim.ZeroTrustAppTokenInfoRespVO;
+import com.dragonsoft.dcuc.approve.utils.ProofsUtil;
+import com.dragonsoft.duceap.base.entity.http.ResponseDTO;
+import com.dragonsoft.duceap.base.entity.security.SecurityUser;
+import com.dragonsoft.duceap.commons.util.ip.IpUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * <p>
+ *
+ * </p>
+ *
+ * @author huangzqa
+ * @date 2023/11/15
+ */
+@Slf4j
+@Component
+public class SecurityUserBusinessImpl implements ISecurityUserBusiness {
+
+    private SecurityAppCache securityAppCache;
+
+    private ISecurityAppResolver securityAppResolver;
+
+    private SecurityUserCache securityUserCache;
+
+    private ISecurityUserResolver securityAccessResolver;
+
+    @Autowired
+    public void setSecurityAppCache(SecurityAppCache securityAppCache) {
+        this.securityAppCache = securityAppCache;
+    }
+
+    @Autowired
+    public void setSecurityAppResolver(ISecurityAppResolver securityAppResolver) {
+        this.securityAppResolver = securityAppResolver;
+    }
+
+    @Autowired
+    public void setSecurityUserCache(SecurityUserCache securityUserCache) {
+        this.securityUserCache = securityUserCache;
+    }
+
+    @Autowired
+    public void setSecurityAccessResolver(ISecurityUserResolver securityAccessResolver) {
+        this.securityAccessResolver = securityAccessResolver;
+    }
+
+    @Override
+    public SecurityApp getSecurityApp(String appCode) {
+        SecurityApp securityApp = securityAppCache.getIfPresent(appCode);
+        if (ObjectUtil.isNull(securityApp)) {
+            securityApp = securityAppResolver.resolve(appCode).orElse(null);
+            if (ObjectUtil.isNotNull(securityApp)) {
+                securityAppCache.put(appCode, securityApp);
+            }
+        }
+        return securityApp;
+    }
+
+    @Override
+    public ResponseDTO<SecurityUser> getSecurityUser(String idcard, String appCode) {
+        SecurityApp securityApp = getSecurityApp(appCode);
+        if (ObjectUtil.isNull(securityApp)) {
+            String format = String.format("无法获取到应用:%s", appCode);
+            log.error(format);
+            return ResponseUtil.dtoFail("应用凭据信息无效");
+        }
+
+        SecurityUser securityUser = securityUserCache.getIfPresent(idcard);
+        if (ObjectUtil.isNull(securityUser)) {
+            securityUser = securityAccessResolver.resolve(idcard).orElse(null);
+            if (ObjectUtil.isNotNull(securityUser)) {
+                securityUserCache.put(idcard, securityUser);
+            }
+        }
+
+        if (ObjectUtil.isNull(securityUser)) {
+            String format = String.format("无法获取到用户:%s", appCode);
+            log.error(format);
+            return ResponseUtil.dtoFail("用户凭据信息无效");
+        }
+
+        Map<String, Object> extendtionsMap = securityUser.getExtendtions();
+        if (MapUtil.isEmpty(extendtionsMap)) {
+            extendtionsMap = new HashMap<>(UserExtInfoEnum.values().length);
+        }
+        extendtionsMap.put(UserExtInfoEnum.SECURITY_APP.getValue(), securityApp);
+
+        securityUser.setExtendtions(extendtionsMap);
+
+        return ResponseUtil.newInstance(securityUser);
+    }
+
+    @Override
+    public void setUserExtInfo(SecurityUser securityUser, HttpServletRequest request) {
+
+        Map<String, Object> extendtionsMap = securityUser.getExtendtions();
+        if (MapUtil.isEmpty(extendtionsMap)) {
+            extendtionsMap = new HashMap<>(UserExtInfoEnum.values().length);
+        }
+
+        String realIpAdrress = IpUtils.getRealIpAdrress(request);
+        String userToken = ProofsUtil.getUserToken(request);
+        String appToken = ProofsUtil.getAppToken(request);
+        extendtionsMap.put(UserExtInfoEnum.USER_TOKEN_ID.getValue(), userToken);
+        extendtionsMap.put(UserExtInfoEnum.APP_TOKEN_ID.getValue(), appToken);
+        extendtionsMap.put(UserExtInfoEnum.REQUEST_IP.getValue(), realIpAdrress);
+
+        securityUser.setExtendtions(extendtionsMap);
+    }
+
+    @Override
+    public void setUserExtInfo(SecurityUser securityUser, ZeroTrustAppTokenInfoRespVO appTokenInfo) {
+
+        Map<String, Object> extendtionsMap = securityUser.getExtendtions();
+        if (MapUtil.isEmpty(extendtionsMap)) {
+            extendtionsMap = new HashMap<>(UserExtInfoEnum.values().length);
+        }
+        ZeroTrustAppItemUserTokenInfoRespVO userToken = appTokenInfo.getUserToken();
+        String userTokenId = userToken.getUserTokenId();
+        String requestIp = userToken.getIp();
+        String appTokenId = appTokenInfo.getAppTokenId();
+
+        extendtionsMap.put(UserExtInfoEnum.USER_TOKEN_ID.getValue(), userTokenId);
+        extendtionsMap.put(UserExtInfoEnum.APP_TOKEN_ID.getValue(), appTokenId);
+        extendtionsMap.put(UserExtInfoEnum.REQUEST_IP.getValue(), requestIp);
+
+        securityUser.setExtendtions(extendtionsMap);
+    }
+
+}

+ 0 - 19
approve-core-service/src/main/java/com/dragonsoft/dcuc/approve/config/ApproveConfig.java

@@ -3,7 +3,6 @@ package com.dragonsoft.dcuc.approve.config;
 import com.dragoninfo.dcuc.common.http.SkipSslVerificationHttpRequestFactory;
 import com.dragonsoft.auditlog.collection.qmtj.provider.IRestTemplateProvider;
 import com.dragonsoft.dcuc.approve.constants.ApproveBeanConstants;
-import com.dragonsoft.dcuc.approve.filter.ProofsFilter;
 import com.dragonsoft.dcuc.approve.properties.ApproveProperties;
 import com.dragonsoft.duceap.base.exception.ApplicationException;
 import com.dragonsoft.smtools.loader.SMFactory;
@@ -11,7 +10,6 @@ import com.fasterxml.jackson.databind.DeserializationFeature;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.web.servlet.FilterRegistrationBean;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.web.client.RestTemplate;
@@ -81,21 +79,4 @@ public class ApproveConfig {
         }
     }
 
-
-    @Bean
-    public ProofsFilter proofsFilter() {
-        return new ProofsFilter();
-    }
-
-    @Bean
-    public FilterRegistrationBean<ProofsFilter> filterRegistrationBean() {
-        FilterRegistrationBean<ProofsFilter> filterRegistrationBean = new FilterRegistrationBean<>();
-        filterRegistrationBean.setFilter(proofsFilter());
-        filterRegistrationBean.addUrlPatterns("/api/v1/*");
-        filterRegistrationBean.addUrlPatterns("/api/v2/*");
-        filterRegistrationBean.addUrlPatterns("/v1/*");
-        filterRegistrationBean.setName("proofsFilter");
-        return filterRegistrationBean;
-    }
-
 }

+ 47 - 0
approve-core-service/src/main/java/com/dragonsoft/dcuc/approve/config/ProofConfiguration.java

@@ -0,0 +1,47 @@
+package com.dragonsoft.dcuc.approve.config;
+
+import com.dragonsoft.dcuc.approve.filter.CheckProofsFilter;
+import com.dragonsoft.dcuc.approve.filter.cache.SecurityAppCache;
+import com.dragonsoft.dcuc.approve.filter.cache.SecurityUserCache;
+import com.dragonsoft.dcuc.approve.properties.ProofStarterProperties;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * <p>
+ * DCUC配置类
+ * </p>
+ *
+ * @author huangzqa
+ * @date 2021/9/3
+ */
+@Configuration
+public class ProofConfiguration {
+
+    @Bean
+    @ConditionalOnMissingBean
+    public SecurityUserCache securityUserCache(ProofStarterProperties proofStarterProperties) {
+        return new SecurityUserCache(proofStarterProperties);
+    }
+
+    @Bean
+    @ConditionalOnMissingBean
+    public SecurityAppCache appCache(ProofStarterProperties proofStarterProperties) {
+        return new SecurityAppCache(proofStarterProperties);
+    }
+
+    @ConditionalOnProperty(name = "approve.proof.enable-proofs-filter")
+    @Bean
+    public FilterRegistrationBean<CheckProofsFilter> checkProofsFilter() {
+        FilterRegistrationBean<CheckProofsFilter> filterRegistrationBean = new FilterRegistrationBean<>();
+        filterRegistrationBean.setFilter(new CheckProofsFilter());
+        filterRegistrationBean.addUrlPatterns("/api/v1/*");
+        filterRegistrationBean.addUrlPatterns("/api/v2/*");
+        filterRegistrationBean.addUrlPatterns("/v1/*");
+        filterRegistrationBean.setName("proofsFilter");
+        return filterRegistrationBean;
+    }
+}

+ 7 - 8
approve-core-service/src/main/java/com/dragonsoft/dcuc/approve/facade/api/ApiV1ApproveFacade.java

@@ -5,25 +5,24 @@ import com.baomidou.mybatisplus.core.toolkit.StringUtils;
 import com.dragoninfo.dcuc.app.dto.ResourceRequestParamDTO;
 import com.dragoninfo.dcuc.app.facade.IResourceFacade;
 import com.dragoninfo.dcuc.common.entity.ApiSearchReq;
-import com.dragoninfo.dcuc.common.entity.Proofs;
 import com.dragoninfo.dcuc.common.utils.ResponseUtil;
 import com.dragoninfo.dcuc.common.utils.SearchableUtil;
+import com.dragoninfo.dcuc.common.utils.SecurityUserUtil;
 import com.dragonsoft.dcuc.approve.business.IApproveBusiness;
+import com.dragonsoft.dcuc.approve.business.IApproveCommonBusiness;
 import com.dragonsoft.dcuc.approve.business.IApproveUploadBusiness;
 import com.dragonsoft.dcuc.approve.business.IWorkFlowBusiness;
-import com.dragonsoft.dcuc.approve.model.dto.OperateReqDTO;
 import com.dragonsoft.dcuc.approve.enumresources.ApproveWorkFlowOperationEnum;
 import com.dragonsoft.dcuc.approve.enumresources.PageTypeEnum;
+import com.dragonsoft.dcuc.approve.model.dto.OperateReqDTO;
+import com.dragonsoft.dcuc.approve.model.dto.TaskRequestUserInfoDTO;
 import com.dragonsoft.dcuc.approve.model.req.ApprovalInfoReqVO;
 import com.dragonsoft.dcuc.approve.model.req.ApprovalInfoUpdateReqVO;
 import com.dragonsoft.dcuc.approve.model.req.ApproveOperateReqVO;
 import com.dragonsoft.dcuc.approve.model.req.ApproveRecordReportReqVO;
 import com.dragonsoft.dcuc.approve.model.resp.*;
 import com.dragonsoft.dcuc.approve.model.vo.ApproveTaskRequestVo;
-import com.dragonsoft.dcuc.approve.model.dto.TaskRequestUserInfoDTO;
 import com.dragonsoft.dcuc.approve.properties.ApproveProperties;
-import com.dragonsoft.dcuc.approve.business.IApproveCommonBusiness;
-import com.dragonsoft.dcuc.approve.threadlocal.ThreadLocalProofsHolder;
 import com.dragonsoft.duceap.base.entity.http.ResponseDTO;
 import com.dragonsoft.duceap.base.entity.http.ResponseStatus;
 import com.dragonsoft.duceap.base.entity.security.BaseSecurityUser;
@@ -189,9 +188,9 @@ public class ApiV1ApproveFacade implements IApiV1ApproveFacade {
 
     @Override
     public ResponseDTO<List<BatchTaskOperateRespVO>> batchApproveOperateType(ApiSearchReq apiSearchReq) {
-        Proofs proofs = ThreadLocalProofsHolder.getProofs();
-        String idcard = proofs.getIdcard();
-        String appCode = proofs.getAppCode();
+        BaseSecurityUser currentUser = UserContextUtils.getCurrentUser();
+        String idcard = currentUser.getIdcard();
+        String appCode = SecurityUserUtil.getSecurityAppCode();
         if (StrUtil.isBlank(idcard) || StrUtil.isBlank(appCode)) {
             return ResponseUtil.dtoFail("请传入凭据");
         }

+ 46 - 37
approve-core-service/src/main/java/com/dragonsoft/dcuc/approve/facade/api/ApiV2ApproveFacade.java

@@ -4,26 +4,25 @@ import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.util.StrUtil;
 import com.dragoninfo.dcuc.common.entity.ApiResult;
 import com.dragoninfo.dcuc.common.entity.ApiSearchReq;
-import com.dragoninfo.dcuc.common.entity.Proofs;
 import com.dragoninfo.dcuc.common.utils.ResponseUtil;
 import com.dragoninfo.dcuc.common.utils.SearchableUtil;
+import com.dragoninfo.dcuc.common.utils.SecurityUserUtil;
 import com.dragoninfo.dcuc.duceap.enums.ManageDisposeTypeEnum;
 import com.dragonsoft.dcuc.approve.business.IApproveBusiness;
-import com.dragonsoft.dcuc.approve.business.external.IDcucBusiness;
+import com.dragonsoft.dcuc.approve.business.IApproveCommonBusiness;
 import com.dragonsoft.dcuc.approve.business.IWorkFlowBusiness;
-import com.dragonsoft.dcuc.approve.model.dto.OperateReqDTO;
+import com.dragonsoft.dcuc.approve.business.external.IDcucBusiness;
 import com.dragonsoft.dcuc.approve.enumresources.*;
-import com.dragonsoft.dcuc.approve.model.dto.ApprovalInfoDTO;
 import com.dragonsoft.dcuc.approve.model.ApproveRecordInfo;
+import com.dragonsoft.dcuc.approve.model.dto.ApprovalInfoDTO;
+import com.dragonsoft.dcuc.approve.model.dto.OperateReqDTO;
+import com.dragonsoft.dcuc.approve.model.dto.TaskRequestUserInfoDTO;
 import com.dragonsoft.dcuc.approve.model.req.*;
 import com.dragonsoft.dcuc.approve.model.req.v2.ApproveOperateV2ReqVO;
 import com.dragonsoft.dcuc.approve.model.resp.*;
 import com.dragonsoft.dcuc.approve.model.vo.ApproveTaskRequestVo;
-import com.dragonsoft.dcuc.approve.model.dto.TaskRequestUserInfoDTO;
 import com.dragonsoft.dcuc.approve.model.vo.dcuc.OauthUserVO;
 import com.dragonsoft.dcuc.approve.service.IApproveRecordService;
-import com.dragonsoft.dcuc.approve.business.IApproveCommonBusiness;
-import com.dragonsoft.dcuc.approve.threadlocal.ThreadLocalProofsHolder;
 import com.dragonsoft.duceap.base.entity.http.ResponseDTO;
 import com.dragonsoft.duceap.base.entity.http.ResponseStatus;
 import com.dragonsoft.duceap.base.entity.security.BaseSecurityUser;
@@ -73,9 +72,10 @@ public class ApiV2ApproveFacade implements IApiV2ApproveFacade {
 
     @Override
     public ResponseDTO<String> approveAuthorities(ApprovalInfoAuthReqVO approvalInfoAuthReqVO) {
-        Proofs proofs = ThreadLocalProofsHolder.getProofs();
-        String idcard = proofs.getIdcard();
-        String appCode = proofs.getAppCode();
+
+        BaseSecurityUser currentUser = UserContextUtils.getCurrentUser();
+        String idcard = currentUser.getIdcard();
+        String appCode = SecurityUserUtil.getSecurityAppCode();
         if (StrUtil.isBlank(idcard) || StrUtil.isBlank(appCode)) {
             return ResponseUtil.dtoFail("请传入凭据");
         }
@@ -137,9 +137,10 @@ public class ApiV2ApproveFacade implements IApiV2ApproveFacade {
 
     @Override
     public ResponseStatus updateApprovesAuthorities(ApprovalInfoAuthUpdateReqVO approvalInfoAuthUpdateReqVO) {
-        Proofs proofs = ThreadLocalProofsHolder.getProofs();
-        String idcard = proofs.getIdcard();
-        String appCode = proofs.getAppCode();
+
+        BaseSecurityUser currentUser = UserContextUtils.getCurrentUser();
+        String idcard = currentUser.getIdcard();
+        String appCode = SecurityUserUtil.getSecurityAppCode();
         if (StrUtil.isBlank(idcard) || StrUtil.isBlank(appCode)) {
             return ResponseStatus.fail("请传入凭据");
         }
@@ -194,9 +195,10 @@ public class ApiV2ApproveFacade implements IApiV2ApproveFacade {
 
     @Override
     public ApiResult approvesSearch(ApiSearchReq apiSearchReq) {
-        Proofs proofs = ThreadLocalProofsHolder.getProofs();
-        String idcard = proofs.getIdcard();
-        String appCode = proofs.getAppCode();
+
+        BaseSecurityUser currentUser = UserContextUtils.getCurrentUser();
+        String idcard = currentUser.getIdcard();
+        String appCode = SecurityUserUtil.getSecurityAppCode();
         if (StrUtil.isBlank(idcard) || StrUtil.isBlank(appCode)) {
             return ApiResult.setFailMessage("请传入凭据");
         }
@@ -252,9 +254,10 @@ public class ApiV2ApproveFacade implements IApiV2ApproveFacade {
 
     @Override
     public ResponseStatus recallApprove(String approveNo) {
-        Proofs proofs = ThreadLocalProofsHolder.getProofs();
-        String idcard = proofs.getIdcard();
-        String appCode = proofs.getAppCode();
+
+        BaseSecurityUser currentUser = UserContextUtils.getCurrentUser();
+        String idcard = currentUser.getIdcard();
+        String appCode = SecurityUserUtil.getSecurityAppCode();
         if (StrUtil.isBlank(idcard) || StrUtil.isBlank(appCode)) {
             return ResponseStatus.fail("请传入凭据");
         }
@@ -302,9 +305,10 @@ public class ApiV2ApproveFacade implements IApiV2ApproveFacade {
 
     @Override
     public ResponseStatus deleteApprove(String approveNo) {
-        Proofs proofs = ThreadLocalProofsHolder.getProofs();
-        String idcard = proofs.getIdcard();
-        String appCode = proofs.getAppCode();
+
+        BaseSecurityUser currentUser = UserContextUtils.getCurrentUser();
+        String idcard = currentUser.getIdcard();
+        String appCode = SecurityUserUtil.getSecurityAppCode();
         if (StrUtil.isBlank(idcard) || StrUtil.isBlank(appCode)) {
             return ResponseStatus.fail("请传入凭据");
         }
@@ -331,9 +335,10 @@ public class ApiV2ApproveFacade implements IApiV2ApproveFacade {
 
     @Override
     public ResponseDTO<List<ApproveCommentVo>> approveComments(String approveNo) {
-        Proofs proofs = ThreadLocalProofsHolder.getProofs();
-        String idcard = proofs.getIdcard();
-        String appCode = proofs.getAppCode();
+
+        BaseSecurityUser currentUser = UserContextUtils.getCurrentUser();
+        String idcard = currentUser.getIdcard();
+        String appCode = SecurityUserUtil.getSecurityAppCode();
         if (StrUtil.isBlank(idcard) || StrUtil.isBlank(appCode)) {
             return ResponseUtil.dtoFail("请传入凭据");
         }
@@ -355,9 +360,10 @@ public class ApiV2ApproveFacade implements IApiV2ApproveFacade {
 
     @Override
     public ResponseDTO<TraceProcessAndOverVo> processPic(String approveNo) {
-        Proofs proofs = ThreadLocalProofsHolder.getProofs();
-        String idcard = proofs.getIdcard();
-        String appCode = proofs.getAppCode();
+
+        BaseSecurityUser currentUser = UserContextUtils.getCurrentUser();
+        String idcard = currentUser.getIdcard();
+        String appCode = SecurityUserUtil.getSecurityAppCode();
         if (StrUtil.isBlank(idcard) || StrUtil.isBlank(appCode)) {
             return ResponseUtil.dtoFail("请传入凭据");
         }
@@ -380,9 +386,10 @@ public class ApiV2ApproveFacade implements IApiV2ApproveFacade {
 
     @Override
     public ResponseDTO<ActivityNodeInfoVo> processPicDetail(String approveNo, String taskDefinitionCode, String statusType) {
-        Proofs proofs = ThreadLocalProofsHolder.getProofs();
-        String idcard = proofs.getIdcard();
-        String appCode = proofs.getAppCode();
+
+        BaseSecurityUser currentUser = UserContextUtils.getCurrentUser();
+        String idcard = currentUser.getIdcard();
+        String appCode = SecurityUserUtil.getSecurityAppCode();
         if (StrUtil.isBlank(idcard) || StrUtil.isBlank(appCode)) {
             return ResponseUtil.dtoFail("请传入凭据");
         }
@@ -404,9 +411,10 @@ public class ApiV2ApproveFacade implements IApiV2ApproveFacade {
 
     @Override
     public ResponseDTO<List<ProcessStatusVo>> processStatus(String approveNo) {
-        Proofs proofs = ThreadLocalProofsHolder.getProofs();
-        String idcard = proofs.getIdcard();
-        String appCode = proofs.getAppCode();
+
+        BaseSecurityUser currentUser = UserContextUtils.getCurrentUser();
+        String idcard = currentUser.getIdcard();
+        String appCode = SecurityUserUtil.getSecurityAppCode();
         if (StrUtil.isBlank(idcard) || StrUtil.isBlank(appCode)) {
             return ResponseUtil.dtoFail("请传入凭据");
         }
@@ -429,9 +437,10 @@ public class ApiV2ApproveFacade implements IApiV2ApproveFacade {
 
     @Override
     public ResponseDTO<TaskOperateRespVO> approveOperateType(String approveNo, String pageType) {
-        Proofs proofs = ThreadLocalProofsHolder.getProofs();
-        String idcard = proofs.getIdcard();
-        String appCode = proofs.getAppCode();
+
+        BaseSecurityUser currentUser = UserContextUtils.getCurrentUser();
+        String idcard = currentUser.getIdcard();
+        String appCode = SecurityUserUtil.getSecurityAppCode();
         if (StrUtil.isBlank(idcard) || StrUtil.isBlank(appCode)) {
             return ResponseUtil.dtoFail("请传入凭据");
         }

+ 35 - 40
approve-core-service/src/main/java/com/dragonsoft/dcuc/approve/facade/api/v3/ApiV3ApproveFacade.java

@@ -3,19 +3,20 @@ package com.dragonsoft.dcuc.approve.facade.api.v3;
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.map.MapUtil;
 import cn.hutool.core.util.ObjectUtil;
-import com.dragoninfo.dcuc.common.entity.Proofs;
 import com.dragoninfo.dcuc.common.utils.LangUtil;
 import com.dragoninfo.dcuc.common.utils.ResponseUtil;
 import com.dragoninfo.dcuc.duceap.enums.ManageDisposeTypeEnum;
-import com.dragonsoft.dcuc.approve.business.api.IApproveApiBusiness;
-import com.dragonsoft.dcuc.approve.business.external.IBimBusiness;
-import com.dragonsoft.dcuc.approve.business.external.IDcucBusiness;
+import com.dragonsoft.dcuc.approve.business.IApproveCommonBusiness;
+import com.dragonsoft.dcuc.approve.business.ISecurityUserBusiness;
 import com.dragonsoft.dcuc.approve.business.IWorkFlowBusiness;
 import com.dragonsoft.dcuc.approve.business.api.IApiV3ApproveBusiness;
-import com.dragonsoft.dcuc.approve.model.dto.OperateReqDTO;
+import com.dragonsoft.dcuc.approve.business.api.IApproveApiBusiness;
+import com.dragonsoft.dcuc.approve.business.external.IBimBusiness;
 import com.dragonsoft.dcuc.approve.enumresources.*;
 import com.dragonsoft.dcuc.approve.model.ApproveRecordInfo;
 import com.dragonsoft.dcuc.approve.model.ApproveTaskClass;
+import com.dragonsoft.dcuc.approve.model.dto.OperateReqDTO;
+import com.dragonsoft.dcuc.approve.model.dto.TaskRequestUserInfoDTO;
 import com.dragonsoft.dcuc.approve.model.req.ApprovalInfoReqVO;
 import com.dragonsoft.dcuc.approve.model.req.ResourceInfoReqVO;
 import com.dragonsoft.dcuc.approve.model.req.v3.ZeroTrustApproveCreateReqV3VO;
@@ -27,15 +28,12 @@ import com.dragonsoft.dcuc.approve.model.resp.v3.ZeroTrustApproveCreateV3RespVO;
 import com.dragonsoft.dcuc.approve.model.resp.v3.ZeroTrustMessageRespVO;
 import com.dragonsoft.dcuc.approve.model.resp.v3.ZeroTrustResultDataVO;
 import com.dragonsoft.dcuc.approve.model.vo.ApproveTaskRequestVo;
-import com.dragonsoft.dcuc.approve.model.dto.TaskRequestUserInfoDTO;
-import com.dragonsoft.dcuc.approve.model.vo.dcuc.ApiOrgResultVo;
-import com.dragonsoft.dcuc.approve.model.vo.dcuc.OauthUserVO;
 import com.dragonsoft.dcuc.approve.service.IApproveRecordService;
-import com.dragonsoft.dcuc.approve.business.IApproveCommonBusiness;
 import com.dragonsoft.dcuc.approve.service.IApproveTaskClassService;
-import com.dragonsoft.dcuc.approve.threadlocal.ThreadLocalProofsHolder;
 import com.dragonsoft.duceap.base.entity.http.ResponseDTO;
 import com.dragonsoft.duceap.base.entity.http.ResponseStatus;
+import com.dragonsoft.duceap.base.entity.security.SecurityUser;
+import com.dragonsoft.duceap.base.utils.UserContextUtils;
 import com.dragonsoft.duceap.commons.util.enums.EnumUtils;
 import com.dragonsoft.duceap.commons.util.json.JsonUtils;
 import com.dragonsoft.duceap.duwf.api.model.TaskRequest;
@@ -71,12 +69,17 @@ public class ApiV3ApproveFacade implements IApiV3ApproveFacade {
 
     private IApproveApiBusiness approveApiBusiness;
 
-    private IDcucBusiness dcucBusiness;
-
     private IApproveTaskClassService approveTaskClassService;
 
     private IApiV3ApproveBusiness apiV3ApproveBusiness;
 
+    private ISecurityUserBusiness securityUserBusiness;
+
+    @Autowired
+    public void setSecurityUserBusiness(ISecurityUserBusiness securityUserBusiness) {
+        this.securityUserBusiness = securityUserBusiness;
+    }
+
     @Autowired
     public void setApiV3ApproveBusiness(IApiV3ApproveBusiness apiV3ApproveBusiness) {
         this.apiV3ApproveBusiness = apiV3ApproveBusiness;
@@ -87,11 +90,6 @@ public class ApiV3ApproveFacade implements IApiV3ApproveFacade {
         this.approveTaskClassService = approveTaskClassService;
     }
 
-    @Autowired
-    public void setDcucBusiness(IDcucBusiness dcucBusiness) {
-        this.dcucBusiness = dcucBusiness;
-    }
-
     @Autowired
     public void setApproveApiBusiness(IApproveApiBusiness approveApiBusiness) {
         this.approveApiBusiness = approveApiBusiness;
@@ -154,31 +152,24 @@ public class ApiV3ApproveFacade implements IApiV3ApproveFacade {
             return ZeroTrustResultDataVO.resultEnumMessage(ZeroTrustBusinessRespEnum.TOKEN_FAIL);
         }
         ZeroTrustAppItemUserTokenInfoRespVO userToken = appTokenInfo.getUserToken();
-        String userTokenId = userToken.getUserTokenId();
         String appCode = appTokenInfo.getAppId();
         String applicantIdcard = userToken.getPid();
         String applicantName = userToken.getName();
         String applicantIp = userToken.getIp();
+        String orgCode = userToken.getOrgCode();
 
-        OauthUserVO oauthUserVO = dcucBusiness.getOauthUserInfoByIdcard(applicantIdcard);
-        if (ObjectUtil.isNotNull(oauthUserVO)) {
-            applicantName = oauthUserVO.getName();
+        ResponseDTO<SecurityUser> securityUserResp = securityUserBusiness.getSecurityUser(applicantIdcard, appCode);
+        if (ResponseUtil.isFail(securityUserResp)) {
+            log.error("令牌信息异常:{}", securityUserResp.getMessage());
+            return ZeroTrustResultDataVO.operateFailMessage("令牌信息异常");
         }
 
-        String applicantOrgCode = userToken.getOrgCode();
+        SecurityUser securityUser = ResponseUtil.getResult(securityUserResp);
+        securityUserBusiness.setUserExtInfo(securityUser, appTokenInfo);
+        UserContextUtils.setCurrentUser(securityUser);
 
-        Proofs proofs = Proofs.builder()
-                .appCode(appCode)
-                .idcard(applicantIdcard)
-                .userToken(userTokenId).appToken(appTokenId).build();
-        ThreadLocalProofsHolder.setPoofs(proofs);
-
-        String applicantOrgName = "";
+        String applicantOrgName = securityUser.getSecurityOrgName();
         String applicantPhoneNo = "";
-        ApiOrgResultVo apiOrgResultVo = dcucBusiness.orgInfo(applicantOrgCode);
-        if (ObjectUtil.isNotNull(apiOrgResultVo)) {
-            applicantOrgName = apiOrgResultVo.getFullName();
-        }
 
         // 获取processType并校验
         WorkflowProcessVo workflowProcessVo = workFlowBusiness.queryWorkflowProcessByBusinessCode(processDefId);
@@ -217,7 +208,7 @@ public class ApiV3ApproveFacade implements IApiV3ApproveFacade {
         approvalInfoReqVO.setApplyReason(title + "申请");
         approvalInfoReqVO.setApplicantIdcard(applicantIdcard);
         approvalInfoReqVO.setApplicantName(applicantName);
-        approvalInfoReqVO.setApplicantOrgCode(applicantOrgCode);
+        approvalInfoReqVO.setApplicantOrgCode(orgCode);
         approvalInfoReqVO.setApplicantOrgName(applicantOrgName);
         approvalInfoReqVO.setApplicantPhoneNo(applicantPhoneNo);
         approvalInfoReqVO.setPermissionValidType(PermissionValidTypeEnum.LONG.getValue());
@@ -263,16 +254,20 @@ public class ApiV3ApproveFacade implements IApiV3ApproveFacade {
             return ZeroTrustResultDataVO.resultEnumMessage(ZeroTrustBusinessRespEnum.TOKEN_FAIL);
         }
         ZeroTrustAppItemUserTokenInfoRespVO userToken = appTokenInfo.getUserToken();
-        String userTokenId = userToken.getUserTokenId();
         String appCode = appTokenInfo.getAppId();
         String applicantIdcard = userToken.getPid();
 
-        Proofs proofs = Proofs.builder()
-                .appCode(appCode)
-                .idcard(applicantIdcard)
-                .userToken(userTokenId).appToken(appTokenId).build();
 
-        ThreadLocalProofsHolder.setPoofs(proofs);
+        ResponseDTO<SecurityUser> securityUserResp = securityUserBusiness.getSecurityUser(applicantIdcard, appCode);
+        if (ResponseUtil.isFail(securityUserResp)) {
+            log.error("令牌信息异常:{}", securityUserResp.getMessage());
+            return ZeroTrustResultDataVO.operateFailMessage("令牌信息异常");
+        }
+
+        SecurityUser securityUser = ResponseUtil.getResult(securityUserResp);
+        securityUserBusiness.setUserExtInfo(securityUser, appTokenInfo);
+        UserContextUtils.setCurrentUser(securityUser);
+
 
         String idcard = userToken.getPid();
         ApproveRecordInfo approveRecordInfo = approveRecordService.findByProcessInstanceId(processInstId);

+ 27 - 9
approve-core-service/src/main/java/com/dragonsoft/dcuc/approve/filter/ProofsFilter.java → approve-core-service/src/main/java/com/dragonsoft/dcuc/approve/filter/CheckProofsFilter.java

@@ -2,10 +2,15 @@ package com.dragonsoft.dcuc.approve.filter;
 
 import cn.hutool.core.util.StrUtil;
 import com.dragoninfo.dcuc.common.entity.Proofs;
+import com.dragoninfo.dcuc.common.utils.ResponseUtil;
+import com.dragonsoft.dcuc.approve.business.ISecurityUserBusiness;
 import com.dragonsoft.dcuc.approve.properties.ApproveProperties;
-import com.dragonsoft.dcuc.approve.threadlocal.ThreadLocalProofsHolder;
 import com.dragonsoft.dcuc.approve.utils.ProofsUtil;
+import com.dragonsoft.duceap.base.entity.http.ResponseDTO;
 import com.dragonsoft.duceap.base.entity.http.ResponseStatus;
+import com.dragonsoft.duceap.base.entity.security.SecurityUser;
+import com.dragonsoft.duceap.base.utils.UserContextUtils;
+import com.dragonsoft.duceap.core.spring.SpringUtils;
 import com.dragonsoft.duceap.web.utils.ResponseUtils;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -28,31 +33,44 @@ import java.io.IOException;
  */
 @Component
 @Slf4j
-public class ProofsFilter extends OncePerRequestFilter {
+public class CheckProofsFilter extends OncePerRequestFilter {
 
-    @Autowired
     private ApproveProperties approveProperties;
 
+    @Autowired
+    public void setApproveProperties(ApproveProperties approveProperties) {
+        this.approveProperties = approveProperties;
+    }
+
     @Override
     protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
 
-        ThreadLocalProofsHolder.remove();
-
         String defaultAppCode = approveProperties.getAppCode();
         Proofs proofs = ProofsUtil.generalProofs(request, defaultAppCode);
 
-        ThreadLocalProofsHolder.setPoofs(proofs);
-
         String idcard = proofs.getIdcard();
         String appCode = proofs.getAppCode();
-        if (StrUtil.isBlank(idcard) || StrUtil.isBlank(appCode)) {
+
+        if (!(StrUtil.isNotBlank(idcard) && StrUtil.isNotBlank(appCode))) {
             ResponseStatus responseStatus = ResponseStatus.fail("请传入凭据");
             ResponseUtils.outJson(responseStatus, response);
             return;
         }
+        ISecurityUserBusiness securityUserBusiness = SpringUtils.getBean(ISecurityUserBusiness.class);
+
+        ResponseDTO<SecurityUser> securityUserResp = securityUserBusiness.getSecurityUser(idcard, appCode);
+        if (ResponseUtil.isFail(securityUserResp)) {
+            ResponseStatus responseStatus = ResponseStatus.fail(securityUserResp.getMessage());
+            ResponseUtils.outJson(responseStatus, response);
+            return;
+        }
+        SecurityUser securityUser = ResponseUtil.getResult(securityUserResp);
+
+        securityUserBusiness.setUserExtInfo(securityUser, request);
+
+        UserContextUtils.setCurrentUser(securityUser);
 
         filterChain.doFilter(request, response);
     }
 
-
 }

+ 25 - 0
approve-core-service/src/main/java/com/dragonsoft/dcuc/approve/filter/cache/ISecurityAppResolver.java

@@ -0,0 +1,25 @@
+package com.dragonsoft.dcuc.approve.filter.cache;
+
+import com.dragoninfo.dcuc.common.entity.SecurityApp;
+
+import java.util.Optional;
+
+/**
+ * <p>
+ * 获取应用信息
+ * </p>
+ *
+ * @author huangzqa
+ * @date 2021/9/3
+ */
+public interface ISecurityAppResolver {
+
+    /**
+     * 获取应用信息
+     *
+     * @param appCode 应用代码
+     * @return 应用信息
+     */
+    Optional<SecurityApp> resolve(String appCode);
+
+}

+ 25 - 0
approve-core-service/src/main/java/com/dragonsoft/dcuc/approve/filter/cache/ISecurityUserResolver.java

@@ -0,0 +1,25 @@
+package com.dragonsoft.dcuc.approve.filter.cache;
+
+import com.dragonsoft.duceap.base.entity.security.SecurityUser;
+
+import java.util.Optional;
+
+/**
+ * <p>
+ * 获取用户信息
+ * </p>
+ *
+ * @author huangzqa
+ * @date 2021/9/3
+ */
+public interface ISecurityUserResolver {
+
+    /**
+     * 获取用户信息
+     *
+     * @param idcard 用户外部ID
+     * @return 用户信息
+     */
+    Optional<SecurityUser> resolve(String idcard);
+
+}

+ 50 - 0
approve-core-service/src/main/java/com/dragonsoft/dcuc/approve/filter/cache/SecurityAppCache.java

@@ -0,0 +1,50 @@
+package com.dragonsoft.dcuc.approve.filter.cache;
+
+import com.dragoninfo.dcuc.common.entity.SecurityApp;
+import com.dragonsoft.dcuc.approve.properties.ProofStarterProperties;
+import com.dragonsoft.duceap.commons.util.string.StringUtils;
+import com.github.benmanes.caffeine.cache.Cache;
+import com.github.benmanes.caffeine.cache.Caffeine;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * <p>
+ * 应用缓存
+ * </p>
+ *
+ * @author huangzqa
+ * @date 2021/9/3
+ */
+public class SecurityAppCache {
+
+    private final Cache<String, SecurityApp> caffeineCache;
+
+    public SecurityAppCache(ProofStarterProperties proofStarterProperties) {
+        ProofStarterProperties.AppCache appCache = proofStarterProperties.getAppCache();
+        this.caffeineCache = Caffeine.newBuilder()
+                .expireAfterWrite(appCache.getExpireAfterWrite(), TimeUnit.SECONDS)
+                .initialCapacity(appCache.getInitialCapacity())
+                .maximumSize(appCache.getMaximumSize())
+                .build();
+    }
+
+    private String cacheKey(String... names) {
+        return "cacheAppKey_" + StringUtils.join(names, "&");
+    }
+
+    public SecurityApp getIfPresent(String... key) {
+        String cacheKey = cacheKey(key);
+        return this.caffeineCache.getIfPresent(cacheKey);
+    }
+
+    public void put(String key, SecurityApp value) {
+        String cacheKey = cacheKey(key);
+        this.caffeineCache.put(cacheKey, value);
+    }
+
+    public void remove(String... keys) {
+        String cacheKey = cacheKey(keys);
+        this.caffeineCache.invalidate(cacheKey);
+    }
+}

+ 43 - 0
approve-core-service/src/main/java/com/dragonsoft/dcuc/approve/filter/cache/SecurityAppResolver.java

@@ -0,0 +1,43 @@
+package com.dragonsoft.dcuc.approve.filter.cache;
+
+import com.dragoninfo.dcuc.app.entity.ApplyInfo;
+import com.dragoninfo.dcuc.app.facade.IApplyInfoFacade;
+import com.dragoninfo.dcuc.common.entity.SecurityApp;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.Optional;
+
+/**
+ * <p>
+ *
+ * </p>
+ *
+ * @author huangzqa
+ * @date 2021/9/6
+ */
+@Component
+public class SecurityAppResolver implements ISecurityAppResolver {
+
+    private IApplyInfoFacade appInfoFacade;
+
+    @Autowired
+    public void setAppInfoFacade(IApplyInfoFacade appInfoFacade) {
+        this.appInfoFacade = appInfoFacade;
+    }
+
+    @Override
+    public Optional<SecurityApp> resolve(String appCode) {
+        ApplyInfo appInfo = appInfoFacade.getAppByCode(appCode);
+        if (appInfo == null) {
+            return Optional.empty();
+        }
+        SecurityApp securityApp = new SecurityApp();
+        securityApp.setAppCode(appInfo.getApplyCode());
+        securityApp.setAppName(appInfo.getApplyName());
+        securityApp.setOrgCode(appInfo.getOrgId());
+        securityApp.setManageOrgCode(appInfo.getManagerOrgId());
+        securityApp.setAppUrl(appInfo.getApplyUrl());
+        return Optional.of(securityApp);
+    }
+}

+ 50 - 0
approve-core-service/src/main/java/com/dragonsoft/dcuc/approve/filter/cache/SecurityUserCache.java

@@ -0,0 +1,50 @@
+package com.dragonsoft.dcuc.approve.filter.cache;
+
+import com.dragonsoft.dcuc.approve.properties.ProofStarterProperties;
+import com.dragonsoft.duceap.base.entity.security.SecurityUser;
+import com.dragonsoft.duceap.commons.util.string.StringUtils;
+import com.github.benmanes.caffeine.cache.Cache;
+import com.github.benmanes.caffeine.cache.Caffeine;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * <p>
+ * 用户信息缓存
+ * </p>
+ *
+ * @author huangzqa
+ * @date 2021/9/3
+ */
+public class SecurityUserCache {
+
+    private final Cache<String, SecurityUser> caffeineCache;
+
+    public SecurityUserCache(ProofStarterProperties proofStarterProperties) {
+        ProofStarterProperties.UserCache userCache = proofStarterProperties.getUserCache();
+        this.caffeineCache = Caffeine.newBuilder()
+                .expireAfterWrite(userCache.getExpireAfterWrite(), TimeUnit.SECONDS)
+                .initialCapacity(userCache.getInitialCapacity())
+                .maximumSize(userCache.getMaximumSize())
+                .build();
+    }
+
+    private String cacheKey(String... names) {
+        return "cacheUserKey_" + StringUtils.join(names, "&");
+    }
+
+    public SecurityUser getIfPresent(String... key) {
+        String cacheKey = cacheKey(key);
+        return this.caffeineCache.getIfPresent(cacheKey);
+    }
+
+    public void put(String key, SecurityUser value) {
+        String cacheKey = cacheKey(key);
+        this.caffeineCache.put(cacheKey, value);
+    }
+
+    public void remove(String... keys) {
+        String cacheKey = cacheKey(keys);
+        this.caffeineCache.invalidate(cacheKey);
+    }
+}

+ 50 - 0
approve-core-service/src/main/java/com/dragonsoft/dcuc/approve/filter/cache/SecurityUserResolver.java

@@ -0,0 +1,50 @@
+package com.dragonsoft.dcuc.approve.filter.cache;
+
+import com.dragonsoft.dcuc.approve.business.external.IDcucBusiness;
+import com.dragonsoft.dcuc.approve.model.vo.dcuc.OauthUserVO;
+import com.dragonsoft.duceap.base.entity.security.SecurityUser;
+import com.dragonsoft.duceap.base.utils.UserContextUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.Optional;
+
+/**
+ * <p>
+ *
+ * </p>
+ *
+ * @author huangzqa
+ * @date 2021/9/6
+ */
+@Component
+public class SecurityUserResolver implements ISecurityUserResolver {
+
+    private IDcucBusiness dcucBusiness;
+
+
+    @Autowired
+    public void setDcucBusiness(IDcucBusiness dcucBusiness) {
+        this.dcucBusiness = dcucBusiness;
+    }
+
+    @Override
+    public Optional<SecurityUser> resolve(String idcard) {
+        OauthUserVO oauthUserVO = dcucBusiness.getOauthUserInfoByIdcard(idcard);
+        if (oauthUserVO == null) {
+            return Optional.empty();
+        }
+        SecurityUser securityUser = new SecurityUser();
+        securityUser.setId(oauthUserVO.getIdcard());
+        securityUser.setCode(oauthUserVO.getPoliceNumber());
+        securityUser.setUserName(oauthUserVO.getIdcard());
+        securityUser.setIdcard(oauthUserVO.getIdcard());
+        securityUser.setName(oauthUserVO.getName());
+        securityUser.setPoliceNo(oauthUserVO.getPoliceNumber());
+        securityUser.setSecurityOrg(oauthUserVO.getOrgCode());
+        securityUser.setSecurityOrgName(oauthUserVO.getOrgName());
+        // 先设置用户上下文,后续访问用户服务才可请求到
+        UserContextUtils.setCurrentUser(securityUser);
+        return Optional.of(securityUser);
+    }
+}

+ 74 - 0
approve-core-service/src/main/java/com/dragonsoft/dcuc/approve/properties/ProofStarterProperties.java

@@ -0,0 +1,74 @@
+package com.dragonsoft.dcuc.approve.properties;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+import java.util.Collections;
+import java.util.Set;
+
+/**
+ * <p>
+ * 配置属性信息
+ * </p>
+ *
+ * @author huangzqa
+ * @date 2021/9/3
+ */
+@Data
+@ConfigurationProperties(prefix = "approve.proof")
+public class ProofStarterProperties {
+
+    /**
+     * 开启凭据过滤
+     */
+    private Boolean enableProofsFilter = true;
+
+    /**
+     * 用户缓存
+     */
+    private UserCache userCache = new UserCache();
+
+    /**
+     * 应用缓存
+     */
+    private AppCache appCache = new AppCache();
+
+    @Data
+    public static class UserCache {
+        /**
+         * 写入失效时间,单位:秒
+         */
+        private Long expireAfterWrite = 1800L;
+        /**
+         * 初始化容量
+         */
+        private Integer initialCapacity = 100;
+
+        /**
+         * 最大容量
+         */
+        private Long maximumSize = 100000L;
+    }
+
+    @Data
+    public static class AppCache {
+        /**
+         * 写入失效时间,单位:秒
+         */
+        private Long expireAfterWrite = 1800L;
+        /**
+         * 初始化容量
+         */
+        private Integer initialCapacity = 100;
+
+        /**
+         * 最大容量
+         */
+        private Long maximumSize = 1000L;
+    }
+
+    /**
+     * IP白名单
+     */
+    private Set<String> ipWitheList = Collections.emptySet();
+}

+ 0 - 31
approve-core-service/src/main/java/com/dragonsoft/dcuc/approve/threadlocal/ThreadLocalProofsHolder.java

@@ -1,31 +0,0 @@
-package com.dragonsoft.dcuc.approve.threadlocal;
-
-import com.alibaba.ttl.TransmittableThreadLocal;
-import com.dragoninfo.dcuc.common.entity.Proofs;
-
-/**
- * <p>
- * 接口请求凭据信息
- * </p>
- *
- * @author huangzqa
- * @date 2021/8/18
- */
-public class ThreadLocalProofsHolder {
-    public static String key = "threadLocalProofsHolder";
-
-    private static final TransmittableThreadLocal<Proofs> PROOFS_THREAD_LOCAL = new TransmittableThreadLocal<>();
-
-    public static Proofs getProofs() {
-        return PROOFS_THREAD_LOCAL.get();
-    }
-
-    public static void setPoofs(Proofs poofs) {
-        PROOFS_THREAD_LOCAL.set(poofs);
-    }
-
-    public static void remove() {
-        PROOFS_THREAD_LOCAL.remove();
-    }
-
-}

+ 59 - 5
approve-core-service/src/main/java/com/dragonsoft/dcuc/approve/utils/ProofsUtil.java

@@ -1,16 +1,22 @@
 package com.dragonsoft.dcuc.approve.utils;
 
+import cn.hutool.core.lang.Assert;
+import cn.hutool.core.map.MapUtil;
 import cn.hutool.core.util.StrUtil;
 import com.alibaba.fastjson.JSONObject;
 import com.dragoninfo.dcuc.common.Constants;
 import com.dragoninfo.dcuc.common.entity.Proofs;
-import com.dragonsoft.dcuc.approve.threadlocal.ThreadLocalProofsHolder;
+import com.dragoninfo.dcuc.common.enums.UserExtInfoEnum;
+import com.dragoninfo.dcuc.common.utils.SecurityUserUtil;
 import com.dragonsoft.duceap.base.entity.security.BaseSecurityUser;
+import com.dragonsoft.duceap.base.entity.security.SecurityUser;
 import com.dragonsoft.duceap.base.utils.UserContextUtils;
 import com.dragonsoft.duceap.commons.util.json.JsonUtils;
+import org.springframework.http.HttpHeaders;
 import org.springframework.util.Base64Utils;
 
 import javax.servlet.http.HttpServletRequest;
+import java.util.Map;
 import java.util.Optional;
 
 /**
@@ -30,10 +36,6 @@ public class ProofsUtil {
         if (currentUser != null) {
             return currentUser.getIdcard();
         }
-        Proofs proofs = ThreadLocalProofsHolder.getProofs();
-        if (proofs != null) {
-            return proofs.getIdcard();
-        }
         return "";
     }
 
@@ -161,4 +163,56 @@ public class ProofsUtil {
         }
         return Optional.empty();
     }
+
+    /**
+     * 生成请求头
+     *
+     * @return 请求头信息
+     */
+    public static HttpHeaders buildHttpHeaders() {
+        SecurityUser currentUser = UserContextUtils.getCurrentUser();
+        return buildHttpHeaders(currentUser);
+    }
+
+    /**
+     * 生成请求头信息
+     *
+     * @param currentUser 当前用户
+     * @return 请求头信息
+     */
+    public static HttpHeaders buildHttpHeaders(SecurityUser currentUser) {
+        Assert.notNull(currentUser);
+        Map<String, Object> extendtions = currentUser.getExtendtions();
+
+        HttpHeaders headers = new HttpHeaders();
+        if (MapUtil.isEmpty(extendtions)) {
+            return headers;
+        }
+        String userToken = extendtions.getOrDefault(UserExtInfoEnum.USER_TOKEN_ID.getValue(), "")
+                .toString();
+
+        String appToken = extendtions.getOrDefault(UserExtInfoEnum.APP_TOKEN_ID.getValue(), "")
+                .toString();
+        String idcard = currentUser.getIdcard();
+        String appCode = SecurityUserUtil.getSecurityAppCode();
+
+        if (StrUtil.isNotBlank(appToken)) {
+            //应用token
+            headers.add("appToken", appToken);
+        }
+        if (StrUtil.isNotBlank(userToken)) {
+            //用户token
+            headers.add("userToken", userToken);
+        }
+
+        if (StrUtil.isNotBlank(idcard)) {
+            headers.add("idcard", idcard);
+        }
+
+        if (StrUtil.isNotBlank(appCode)) {
+            headers.add("appCode", appCode);
+        }
+
+        return headers;
+    }
 }