WSO APIM 2.1.0 - 如何访问请求中的 HTTP POST 参数

WSO APIM 2.1.0 - how do I access HTTP POST parameters in a request

用例:我们有一个现有的产品API。我们打算使用 API Manager 作为 pass-through 中介,以便在我们现有的 API 上利用节流和分析。

我们编写了一个自定义身份验证处理程序,它在默认 APIAuthenticationHandler 的上游加载。这允许我们通过自定义 header X-Auth-Token 来识别我们的用户,而不是 WSO2 OAuth 令牌 - 这部分对于经过身份验证的路由工作正常。

不幸的是,这不允许我们识别访问我们身份验证路由的用户,结果我们的分析数据因大量 'Unknown' 用户而出现偏差。

我一直在尝试找出如何在我们的自定义身份验证处理程序中访问用户登录的 HTTP POST 参数,但我终究无法弄清楚 Synapse 将其存储在树中的位置classes.

网上各种建议,比如通过

访问HttpServletRequest
HttpServletRequest servletRequest = (HttpServletRequest) messageContext.getProperty(HTTPConstants.MC_HTTP_SERVLETREQUEST);

不工作。

参数不能作为 MessageContext 或 Axis2MessageContext 中的属性使用 objects。

log_in_message.xml 调解器记录了一个包含我所需参数的 SOAP 信封:

Envelope: <?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
  <soapenv:Body>
    <xformValues>
      <api_key>*expunged*</api_key>
      <login_id>testy.user</login_id>
    </xformValues>
  </soapenv:Body>
</soapenv:Envelope> {org.apache.synapse.mediators.builtin.LogMediator}

但在我的自定义处理程序中,消息上下文中只有一个空的 SoapEnvelope:

[PassThru] <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"><soapenv:Body/></soapenv:Envelope>

我也无法找到一个明显的调解模式来添加到我们的 API 的突触序列中,以便将此 REST 参数注入消息上下文中的 属性。我在网上找到的所有内容都涉及向 URI 动态添加参数。

有问题的请求是 HTTP 1.1 POST(内容类型 x-www-form-encoded),下游服务已成功处理,因此参数肯定包含在内。

谁能建议我从中介树中的 java class 中获取 HTTP POST body 或 body 参数的方法还是在自定义处理程序中?

谢谢

编辑:对于那些在未来某个时间来到这里的人来说,事实证明它就像在我的处理程序中调用调解器一样简单:

public boolean handleRequest(MessageContext messageContext) {
    ...
    // mediate
    // In order to avoid a remote registry call occurring on each invocation, we
    // directly get the extension sequences from the local registry.
    Map localRegistry = messageContext.getConfiguration().getLocalRegistry();

    // run inbound mediations
    String apiName = (String) messageContext.getProperty(RESTConstants.SYNAPSE_REST_API);
    Object sequence = localRegistry.get(apiName + "--In");
    if (sequence instanceof Mediator) {
        ((Mediator) sequence).mediate(messageContext);
    }

编辑 2:Bee 在下面建议的更好的解决方案:

private String getLoginIdFromSoapEnvelope(org.apache.axis2.context.MessageContext axis2MessageContext) {
    String loginId = null;
    try {
        RelayUtils.buildMessage(axis2MessageContext);

        SOAPEnvelope envelope = axis2MessageContext.getEnvelope();
        OMElement root = envelope.getBody().getFirstElement();
        OMElement loginElement = root.getFirstChildWithName(new QName("login_id"));
        loginId = loginElement != null ? loginElement.getText() : null;
    }catch (Exception exc) {
        log.error("Unable to unmarshal via RelayUtils.buildMessage", exc);
    }
    return loginId;
}

试试这个。

 RelayUtils.buildMessage(mc);

 String login_id = mc.getEnvelope().getBody().getFirstElement()
   .getFirstChildWithName(new QName("http://ws.apache.org/ns/synapse", "login_id"))
   .getText();

(这可能需要一些调整.. - 命名空间等)

参考:https://docs.wso2.com/display/ESB500/Sample+380%3A+Writing+your+own+Custom+Mediation+in+Java