乐趣区

关于weblogic:运维攻坚之bpm-token无效问题

背景

某我的项目在 weblogic 降级失败后进行回滚,回滚后环境接口无法访问,报 500 异样,接口为 BPM Service 客户端程序,谬误如下:

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 的逻辑如下

  • 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 就可能无奈被辨认,而后都是朝着这个方向去排查,试了很多计划

  • 两边都将依赖通过 library-ref 形式援用 soa.workflow 库
  • 两个接口放入同一个 war 包
  • 两边都通过间接引入 bpm-service.jar 包形式调用 bpm api

以上形式都失败后,回过头来看谬误日志

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,代码如下

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;
}

比拟外围的代码是以下两行

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 代码如下:

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 包反编译查看代码,的确没有解密就间接用

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 一下子就能找到问题起因,没有服务器权限的运维就是坑。

退出移动版