WSO2 APIM按用户需求过滤API响应字段失效问题排查
问题:WSO2 APIM中Synapse序列无法按用户身份过滤响应字段
用户在WSO2 APIM中尝试通过Synapse序列实现按不同用户身份过滤API响应字段,但执行后目标字段未被删除,使用Script中介器和PayloadFactory均未达到预期效果。当前使用的Script序列如下:
<sequence xmlns="http://ws.apache.org/ns/synapse" name="Final-using-script"> <property name="clientUsername" scope="default" expression="$ctx:api.ut.userId"/> <log level="custom"> <property name="userId" expression="$ctx:clientUsername"/> </log> <script language="js"> <![CDATA[ var payload = mc.getPayloadJSON(); var log = mc.getServiceLog(); log.info(payload); var user = mc.getProperty('clientUsername'); if (user === 'abc@carbon.super') { delete payload.MobileNo; delete payload.EmailID; delete payload.SurveyorName; } else if (user === 'xyz@carbon.super') { delete payload.InsClaimNo; delete payload.Acknowledgment; delete payload.RejectionMsg; } mc.setPayloadJSON(payload); ]]> </script> </sequence>
排查及解决方法
1. 确认用户身份属性获取正确性
- 查看日志中输出的
userId值,若为空或与预期不符,说明$ctx:api.ut.userId属性在当前环境中无效 - 替换为
$ctx:REMOTE_USER或$ctx:USER_ID(不同WSO2版本的用户身份属性键可能不同) - 也可在脚本中直接调用API获取用户名:
var user = mc.getUserRealm().getUserStoreManager().getUserClaimValue(mc.getRemoteUser(), "http://wso2.org/claims/username", null);
2. 检查响应Payload结构
- 若API响应是嵌套JSON(如
{"response": {"MobileNo": "xxx", ...}}),脚本中直接操作payload.MobileNo会找不到对应字段 - 需先定位到实际包含字段的层级,示例调整:
var payload = mc.getPayloadJSON(); var responseData = payload.response; // 假设字段在response节点下 if (user === 'abc@carbon.super') { delete responseData.MobileNo; delete responseData.EmailID; delete responseData.SurveyorName; } mc.setPayloadJSON(payload);
3. 确认序列执行时机
- 该序列必须绑定到API的响应流(Out Sequence),若配置在请求流(In Sequence)则不会处理返回的响应数据
- 检查API的序列配置,确保响应流关联的是
Final-using-script序列
4. PayloadFactory替代实现(更稳定)
如果Script中介器问题无法解决,可使用PayloadFactory精准构造响应,避免字段删除的不确定性:
<sequence xmlns="http://ws.apache.org/ns/synapse" name="Final-using-payloadfactory"> <property name="clientUsername" scope="default" expression="$ctx:api.ut.userId"/> <log level="custom"> <property name="userId" expression="$ctx:clientUsername"/> </log> <payloadFactory media-type="json"> <format> { "CommonField1": "$1", "CommonField2": "$2", <xsl:if test="$ctx:clientUsername = 'abc@carbon.super'"> "InsClaimNo": "$3", "Acknowledgment": "$4", "RejectionMsg": "$5" </xsl:if> <xsl:if test="$ctx:clientUsername = 'xyz@carbon.super'"> "MobileNo": "$6", "EmailID": "$7", "SurveyorName": "$8" </xsl:if> } </format> <args> <arg evaluator="json" expression="$.CommonField1"/> <arg evaluator="json" expression="$.CommonField2"/> <arg evaluator="json" expression="$.InsClaimNo"/> <arg evaluator="json" expression="$.Acknowledgment"/> <arg evaluator="json" expression="$.RejectionMsg"/> <arg evaluator="json" expression="$.MobileNo"/> <arg evaluator="json" expression="$.EmailID"/> <arg evaluator="json" expression="$.SurveyorName"/> </args> </payloadFactory> </sequence>
- 注意:需根据实际响应字段调整
<format>和<args>中的内容,列出所有需要保留的字段,通过<xsl:if>根据用户身份动态包含对应字段 - 若字段较多,可结合
<switch>中介器分用户类型配置不同的PayloadFactory
5. 开启调试日志定位问题
- 在WSO2 APIM的
repository/conf/log4j2.properties中添加:log4j.logger.org.apache.synapse.mediators.bsf.ScriptMediator=DEBUG - 查看脚本中
log.info(payload)输出的内容,确认Payload结构、用户身份值是否与预期一致,排查字段删除逻辑是否执行
内容的提问来源于stack exchange,提问作者Yashwin Tm
相关产品推荐
相关产品推荐

