WSO2 Micro Integrator令牌跨后端传递失败及最佳方案咨询
WSO2 Micro Integrator 令牌传递场景问题解决
问题分析
当前API在调用令牌接口后,未清除或重置请求体,导致令牌接口返回的包含token_type字段的JSON响应被直接作为请求体发送给第二个后端,而第二个后端的ext_APICreateOffre操作不接受该参数,因此触发错误。
修正方案
核心解决点是在调用令牌接口前保存原始请求体,获取令牌后恢复原始请求体,避免将令牌响应作为第二个后端的请求 payload。修改后的配置如下:
<?xml version="1.0" encoding="UTF-8"?> <api context="/crmtest" name="crmtest" xmlns="http://ws.apache.org/ns/synapse"> <resource methods="POST" uri-template="/crm1"> <inSequence> <!-- 保存用户原始请求体到属性 --> <property name="ORIGINAL_PAYLOAD" scope="default" expression="$body"/> <!-- 构造令牌请求参数 --> <property name="client_id" scope="default" type="STRING" value="************"/> <property name="client_secret" scope="default" type="STRING" value="************"/> <property name="grant_type" scope="default" type="STRING" value="client_credentials"/> <property name="resource" scope="default" type="STRING" value="https://************.com"/> <payloadFactory media-type="xml"> <format> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Body> <root> <client_id>$1</client_id> <client_secret>$2</client_secret> <grant_type>$3</grant_type> <resource>$4</resource> </root> </soapenv:Body> </soapenv:Envelope> </format> <args> <arg evaluator="xml" expression="$ctx:client_id"/> <arg evaluator="xml" expression="$ctx:client_secret"/> <arg evaluator="xml" expression="$ctx:grant_type"/> <arg evaluator="xml" expression="$ctx:resource"/> </args> </payloadFactory> <property name="messageType" scope="axis2" type="STRING" value="application/x-www-form-urlencoded"/> <property name="DISABLE_CHUNKING" scope="axis2" type="STRING" value="true"/> <!-- 调用令牌接口 --> <call> <endpoint> <http method="post" uri-template="https://login.microsoftonline.com/************f/oauth2/token"> <suspendOnFailure> <initialDuration>-1</initialDuration> <progressionFactor>-1</progressionFactor> <maximumDuration>0</maximumDuration> </suspendOnFailure> <markForSuspension> <retriesBeforeSuspension>0</retriesBeforeSuspension> </markForSuspension> </http> </endpoint> </call> <!-- 提取令牌 --> <property name="token" scope="default" type="STRING" expression="json-eval($.access_token)"/> <log> <property expression="get-property('token')" name="tt"/> </log> <!-- 恢复用户原始请求体 --> <payloadFactory media-type="xml"> <format>$1</format> <args> <arg evaluator="xml" expression="$ctx:ORIGINAL_PAYLOAD"/> </args> </payloadFactory> <!-- 恢复原始请求的content-type --> <property name="messageType" scope="axis2" expression="$trp:Content-Type"/> <!-- 设置Authorization头 --> <property expression="concat('Bearer ', get-property('token'))" name="Authorization" scope="transport" type="STRING"/> <!-- 调用业务后端 --> <call> <endpoint> <http method="post" uri-template="https://************.com/api/data/v9.2/ext_APICreateOffre"> <suspendOnFailure> <initialDuration>-1</initialDuration> <progressionFactor>-1</progressionFactor> <maximumDuration>0</maximumDuration> </suspendOnFailure> <markForSuspension> <retriesBeforeSuspension>0</retriesBeforeSuspension> </markForSuspension> </http> </endpoint> </call> <respond/> </inSequence> <outSequence/> <faultSequence/> </resource> </api>
修改说明
- 新增
ORIGINAL_PAYLOAD属性保存用户原始请求体,避免令牌接口的响应覆盖原始请求内容。 - 在获取令牌后,通过
payloadFactory恢复原始请求体,并重置messageType为原始请求的Content-Type。
优化建议
- 令牌缓存:每次请求都调用令牌接口会降低性能,可将令牌缓存到分布式缓存或MI的本地缓存中,设置缓存过期时间匹配令牌的
expires_in字段。 - 使用OAuth2 Mediator:WSO2 MI提供
OAuth2Mediator,可自动处理令牌的获取、缓存和过期刷新,减少手动配置的复杂度。 - 完善错误处理:在
faultSequence中添加令牌获取失败、后端调用失败的日志记录和友好返回逻辑。
内容的提问来源于stack exchange,提问作者Oussama Nairi
相关产品推荐
相关产品推荐

