Azure APIM策略问题:从SOAP请求提取用户名并设置变量
提取SOAP请求中的Username并设置变量的问题
问题背景
我的API收到如下SOAP请求:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://example.com/webservice"> <soapenv:Header> <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="1"> <wsse:UsernameToken> <wsse:Username>myUsername</wsse:Username> <wsse:Password>myPassword</wsse:Password> </wsse:UsernameToken> </wsse:Security> </soapenv:Header> <soapenv:Body> <web:YourRequest> </web:YourRequest> </soapenv:Body> </soapenv:Envelope>
需求是提取请求中的Username字段,将其设置为变量。
尝试的方案及错误
我先尝试将入站请求转换为JSON:
<xml-to-json kind="javascript-friendly" apply="always" consider-accept-header="true" />
然后设置变量:
<set-variable name="jsonBody" value="@(context.Response.Body.As<JObject>(preserveContent: true))"/> <set-variable name="age" value="@((string)((JObject)context.Variables[" jsonBody"])["soapenv$Envelope"]["soapenv$Header"]["wsse$Security"]["wsse$UsernameToken"]["wsse$Username"]["$t"])"/>
但出现了以下错误:
set-variable (0.243 ms) { "messages": [ { "message": "Expression evaluation failed.", "expression": "context.Response.Body.As<JObject>(preserveContent: true)", "details": "Object reference not set to an instance of an object." }, "Expression evaluation failed. Object reference not set to an instance of an object.", "Object reference not set to an instance of an object." ] }
我并非一定要将请求转换为JSON,只是更熟悉JSON处理方式,希望能修正该策略或提供更合适的方案。
修正方案
方案一:修正JSON转换的错误
错误核心原因有两个:
- 错误引用了
context.Response.Body,入站请求应使用context.Request.Body - 变量名
" jsonBody"包含多余空格,导致无法正确读取变量
修正后的配置如下:
<!-- 将XML转换为JSON --> <xml-to-json kind="javascript-friendly" apply="always" consider-accept-header="false" /> <!-- 读取转换后的JSON到变量 --> <set-variable name="jsonBody" value="@(context.Request.Body.As<JObject>(preserveContent: true))" /> <!-- 提取Username到变量 --> <set-variable name="username" value="@((string)((JObject)context.Variables["jsonBody"])["soapenv$Envelope"]["soapenv$Header"]["wsse$Security"]["wsse$UsernameToken"]["wsse$Username"]["$t"])" />
方案二:直接用XPath提取XML(更高效)
不需要转换JSON,直接通过XPath定位XML中的Username元素,步骤更简洁高效:
<set-variable name="username" value="@(context.Request.Body.AsXPathSelectElement("//wsse:Username", new XmlNamespaceManager(new NameTable()) { { "wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" } }).Value)" />
也可以使用extract-variable策略实现:
<extract-variable name="username"> <xpath expression="//wsse:Username" namespace-map="@{ new Dictionary<string, string> { { "wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" } } }" /> </extract-variable>
内容的提问来源于stack exchange,提问作者Victor Mason
相关产品推荐
相关产品推荐

