運維攻堅之bpm token無效問題

背景

某項目在weblogic升級失敗後進行回滾,回滾後環境接口沒法訪問,報500異常,接口爲BPM Service客戶端程序,錯誤以下:java

SEVERE: <.> getTokenType: invalid token: e0FFU31EbGdrK0IxSlV1WkFMM0doc2dlMUJxdWpjQmEza0tzZGNncnlOSUlLdnFaT0QrY1pyanBBa0d0MTdURHhqbmx4SWJ1d3hvMGsxNmZyaUJFcDIvbGd3MkFWUjRCUXVZdFhvemcxZmprQm83akFoS3pMSWVxeG1DT213VkJpUW5rUWhzQ3lVSmRUT204dXdUUmI2bnlsdEg4bTducTFBWVd0eDVKWjdVSHRiRndsRkRxcjQrZnBVKzBoV0lkc1lRZXQ2VlZkSDRtNUp0V05LYW1SdGNMNWZOUE0rVTVtaEhYYWU5czg4c1VLNHIvenFDN05GTXFieGl6YXJubkd6ZHhTSEZRcUxiRTlmK3ZaNzlLMVlCNExmbkJhL0pSY2hvanlHZ0ZyQWJLdVhJbz0=
SEVERE: <.> Invalid Token Error in Verification Service.
Invalid Token Error in Verification Service. Received invalid token in getTokenType.
Verify that correct token is passed.

ORABPEL-30503

Invalid Token Error in Verification Service.
Invalid Token Error in Verification Service. Received invalid token in getTokenType.
Verify that correct token is passed.

    at oracle.bpel.services.workflow.verification.impl.Token.getTokenType(Token.java:545)
    at oracle.bpel.services.workflow.verification.impl.Token.isSameValue(Token.java:314)
    at oracle.bpel.services.workflow.verification.impl.VerificationService.isInternalWorkflowContext(VerificationService.java:689)

排查

從錯誤日誌上看是token問題,首先就要搞清楚token是怎麼來的,通過排查,整理出token的邏輯以下web

  • 1.用戶在登陸頁輸入用戶名密碼登陸
  • 2.後臺登陸bpm獲取token
  • 3.bpm token通過加密後做爲jwt的claim放入jwt token中
  • 4.用戶帶上jwt token獲取代辦
  • 5.後臺解碼jwt token,從jwt中獲取bpm token的claim
  • 6.解密bpm token
  • 7.帶上bpm token調用bpm api

還有一個比較重要的信息是,登陸獲取token的接口和調用bpm api的接口不在同一個war包裏,因此一開始懷疑是兩邊bpm相關jar包版本不同,好比登陸生成token用的jar包和調用bpm api用的jar包若是版本不同,那麼token就可能沒法被識別,而後都是朝着這個方向去排查,試了不少方案npm

  • 兩邊都將依賴經過 library-ref方式引用soa.workflow庫
  • 兩個接口放入同一個war包
  • 兩邊都經過直接引入bpm-service.jar包方式調用bpm api

以上方式都失敗後,回過頭來看錯誤日誌segmentfault

Invalid Token Error in Verification Service.
Invalid Token Error in Verification Service. Received invalid token in getTokenType.
Verify that correct token is passed.

    at oracle.bpel.services.workflow.verification.impl.Token.getTokenType(Token.java:545)
    at oracle.bpel.services.workflow.verification.impl.Token.isSameValue(Token.java:314)
    at oracle.bpel.services.workflow.verification.impl.VerificationService.isInternalWorkflowContext(VerificationService.java:689)

由於該項目的後臺咱們沒有權限,所以也用不了arthas進行調試,但仍是經過其餘環境找到了oracle.bpel.services.workflow.verification.impl.Token.getTokenType(Token.java:545)所在的jar包位置${SOA_HOME}/soa/modules/oracle.soa.workflow_11.1.1/bpm-services.jar,代碼以下api

public static Type getTokenType(String token) throws WorkflowException {
    if (token == null)
        throw new WorkflowException(new IllegalArgumentException());
    List<String> tokenList = CommonUtil.split(token, ";;");
    Type type = Type.GENERIC;
    if (tokenList != null && tokenList.size() < 3) {
        Object[] errorObjs = {"getTokenType"};
        DiagnosticService.log(18, DiagnosticService.DIAGNOSTICS_ERRORS, "getTokenType: invalid token: " + token);
        throw new WorkflowException(30503, errorObjs);
    }
    String typeStr = tokenList.get(1);
    if (Type.GENERIC.toString().equals(typeStr))
        return Type.GENERIC;
    if (Type.INTERNAL.toString().equals(typeStr))
        return Type.INTERNAL;
    if (Type.TASKFLOW_INTERNAL.toString().equals(typeStr))
        return Type.TASKFLOW_INTERNAL;
    return Type.GENERIC;
}

比較核心的代碼是如下兩行bash

List<String> tokenList = CommonUtil.split(token, ";;");
if (tokenList != null && tokenList.size() < 3) {
        Object[] errorObjs = {"getTokenType"};
        DiagnosticService.log(18, DiagnosticService.DIAGNOSTICS_ERRORS, "getTokenType: invalid token: " + token);
        throw new WorkflowException(30503, errorObjs);
}

對token使用分隔符;;進行切割,若是長度小於3那麼就會拋出30503異常和錯誤日誌同樣,但從日誌中咱們能夠看到token爲服務器

e0FFU31EbGdrK0IxSlV1WkFMM0doc2dlMUJxdWpjQmEza0tzZGNncnlOSUlLdnFaT0QrY1pyanBBa0d0MTdURHhqbmx4SWJ1d3hvMGsxNmZyaUJFcDIvbGd3MkFWUjRCUXVZdFhvemcxZmprQm83akFoS3pMSWVxeG1DT213VkJpUW5rUWhzQ3lVSmRUT204dXdUUmI2bnlsdEg4bTducTFBWVd0eDVKWjdVSHRiRndsRkRxcjQrZnBVKzBoV0lkc1lRZXQ2VlZkSDRtNUp0V05LYW1SdGNMNWZOUE0rVTVtaEhYYWU5czg4c1VLNHIvenFDN05GTXFieGl6YXJubkd6ZHhTSEZRcUxiRTlmK3ZaNzlLMVlCNExmbkJhL0pSY2hvanlHZ0ZyQWJLdVhJbz0=

並無分隔符;;,從token的流程能夠看出,token是通過加密,生成token代碼以下:oracle

String wforig = ibpmCntx.getToken();
String wf = Utils.encryptUsingWLES(wforig);
wf = JWTokens.encodeBase64(wf);
claims.put("workflowContext", wf);
  • encryptUsingWLES調用weblogic自身加密服務進行加密,weblogic加密能夠參考以前的這篇文章
  • encodeBase64是把加密過的token進行base64編碼

把token按照base64解密再用weblogic解密後,也確實獲得了正常的token運維

8b261e0a-85e7-4006-88f9-51f4a6baf887;;G;;kHUwUEZ4hbQaZATQaU1gdDDLInpm0Dv7JaDTnUyGKKSXH4qzqQtqi7k+U60mE127gPQhOxPV8M4fZLDzA6Tjm/CaBXHxboiuiNa9EB/dnxeBkU/qI0m+LUsivLbaFDiKCzhTMmGgMiqZPgxv+s3E9A==

能夠看到確實包含分隔符;;因此能夠肯定的是bpm client在解析token是並無解密,下載war包反編譯查看代碼,確實沒有解密就直接用svn

String wf = (String)jw.getClaim("workflowContext");
request.setProperty("workflowContext", wf);

解決

服務器上的ear和svn上的ear都沒有解密的代碼,最後由於幾年前幫這個項目解決過問題無心中留了一個包,找到了正確的包,部署上去後問題解決

String wf = (String)jw.getClaim("workflowContext");
wf = JWTokens.decodeBase64(wf);
wf = Utils.decryptUsingWLES(wf);

request.setProperty("workflowContext", wf);

總結

若是有服務器權限實這個問題用arthas一會兒就能找到問題緣由,沒有服務器權限的運維就是坑。

相關文章
相關標籤/搜索