【问题标题】:How to submit SOAP request with auth headers in PHP?如何在 PHP 中提交带有 auth 标头的 SOAP 请求?
【发布时间】:2018-06-18 22:36:15
【问题描述】:

我正在使用 SOAP 网络服务 (https://servisi.bisnode.si/BisnodeWebService/BisnodeWebService.asmx?WSDL)

(方法在这里描述:https://servisi.bisnode.si/BisnodeWebService/BisnodeWebService.asmx?op=GetData_PodjetjeReport

到目前为止,服务是通过不安全的连接 (http://servisi.gvin.com) 访问的,但提供商已切换到 https (https://servisi.bisnode.si)。

这是我的 PHP 代码:

$insecure = 'http://servisi.gvin.com';
$secure = 'https://servisi.bisnode.si';

$soapClient = new SoapClient($insecure."/BisnodeWebService/BisnodeWebService.asmx?WSDL", array('trace' => 1, 'exceptions' => 0));
$header = new SoapHeader($insecure.'/BisnodeWebService', 'AuthHeader', array('Username' => '[user]', 'Password' => '[pass]'));

$soapClient->__setSoapHeaders($header);

$result = $soapClient->GetData_PodjetjeReport(array('sMSorDS' => '1234567'));

echo "====== REQUEST HEADERS =====" . PHP_EOL;
var_dump($soapClient->__getLastRequestHeaders());

echo "========= REQUEST ==========" . PHP_EOL;
var_dump($soapClient->__getLastRequest());

echo "========= RESPONSE ==========" . PHP_EOL;
var_dump($result);

当我使用 $insecure 时,请求是这样的:

====== REQUEST HEADERS =====
string(276) "POST /BisnodeWebService/BisnodeWebService.asmx HTTP/1.1
Host: servisi.gvin.com
Connection: Keep-Alive
User-Agent: PHP-SOAP/5.5.38
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://servisi.gvin.com/BisnodeWebService/GetData_PodjetjeReport"
Content-Length: 460

========= REQUEST ==========
string(460) "
[user][pass]1234567
"

在这种情况下,一切都按预期工作。 但是当我使用 $secure 时,会发生这种情况:

====== REQUEST HEADERS =====
string(278) "POST /BisnodeWebService/BisnodeWebService.asmx HTTP/1.1
Host: servisi.bisnode.si
Connection: Keep-Alive
User-Agent: PHP-SOAP/5.5.38
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://servisi.gvin.com/BisnodeWebService/GetData_PodjetjeReport"
Content-Length: 553

========= REQUEST ==========
string(553) "
Username[user]Password[pass]1234567
"

请注意 REQUEST 部分,其中字符串中包含额外的“用户名”和“密码”部分。

这会导致身份验证失败。

为什么会出现差异以及如何解决?

我尝试向肥皂请求添加不同的参数,但没有成功。

感谢您的帮助!

-- 编辑--

在@Daniel O 的帮助下,我成功地向前迈出了一步。

这是我使用 $secure 时得到的 XML:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://servisi.gvin.com/BisnodeWebService" xmlns:ns2="https://servisi.bisnode.si/BisnodeWebService">
    <SOAP-ENV:Header>
        <ns2:AuthHeader>
            <Username>[user]</Username>
            <Password>[pass]</Password>
        </ns2:AuthHeader>
    </SOAP-ENV:Header>
    <SOAP-ENV:Body>
        <ns1:GetData_PodjetjeReport>
            <ns1:sMSorDS>1234567</ns1:sMSorDS>
        </ns1:GetData_PodjetjeReport>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

我不知道为什么,但是创建了一个额外的命名空间。我想这不会是一个问题,如果用户名和密码标签将以 ns2 为前缀,就像 AuthHeader 一样。

现在这就是我在使用 $insecure 时得到的(这有效):

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://servisi.gvin.com/BisnodeWebService">
    <SOAP-ENV:Header>
        <ns1:AuthHeader>
            <ns1:Username>[user]</ns1:Username>
            <ns1:Password>[pass]</ns1:Password>
        </ns1:AuthHeader>
    </SOAP-ENV:Header>
    <SOAP-ENV:Body>
        <ns1:GetData_PodjetjeReport>
            <ns1:sMSorDS>1234567</ns1:sMSorDS>
        </ns1:GetData_PodjetjeReport>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

如何解决这个问题?

【问题讨论】:

    标签: php web-services soap https


    【解决方案1】:

    AuthHeader 数据必须是 stdClass(而不是数组)。

    $soapClient = new SoapClient('https://servisi.bisnode.si/BisnodeWebService/BisnodeWebService.asmx?WSDL', [
        'trace' => 1,
        'exceptions' => 0,
    ]);
    
    // Must be a stdClass (and not an array)
    $auth = new stdClass();
    $auth->Username = '[username]';
    $auth->Password = '[password]';
    
    $header = new SoapHeader('http://servisi.gvin.com/BisnodeWebService', 'AuthHeader', $auth);
    
    $soapClient->__setSoapHeaders($header);
    
    $result = $soapClient->GetData_PodjetjeReport(array('sMSorDS' => '1234567'));
    
    echo "====== REQUEST HEADERS =====" . PHP_EOL;
    var_dump($soapClient->__getLastRequestHeaders());
    
    echo "========= REQUEST ==========" . PHP_EOL;
    var_dump($soapClient->__getLastRequest());
    
    echo "========= RESPONSE ==========" . PHP_EOL;
    var_dump($result);
    

    标题结果:

    <SOAP-ENV:Header><ns1:AuthHeader><ns1:Username>[username]</ns1:Username><ns1:Password>[password]</ns1:Password></ns1:AuthHeader></SOAP-ENV:Header>
    

    【讨论】:

    • 感谢您的回答。我知道​​我需要在每个请求中发送 Auth 标头。我确实设法使用 cURL 和发布 XML 让它工作,但这不是我发布这个问题的原因。我想弄清楚为什么请求字符串不同,当使用具有相同设置的 PHP SOAP 客户端时,只是一个不同的 URL(http 与 https)。
    • 非常感谢您的帮助。我已经尝试过停用验证,但没有成功:(请求字符串中还有额外的“用户名”和“密码”字符串。
    • 用 stdClass 代替数组试试。
    • PS:您还应该将 PHP 至少更新到版本 5.6,或更好的 7.x
    • 多亏了你,我才迈出了一步。我使用对象而不是数组,生成的 XML 现在几乎可以了。如果你能看一下,我更新了我原来的问题。谢谢!
    【解决方案2】:

    AuthHeader 不需要使用 stdClass。它应该适用于 SoapVar。

    <?php
    
    $insecure = 'http://servisi.gvin.com';
    $secure = 'https://servisi.bisnode.si';
    
    $soapClient = new SoapClient($secure."/BisnodeWebService/BisnodeWebService.asmx?WSDL", array('trace' => 1, 'exceptions' => 0));
    $auth = new SoapVar(array('ns2:Username' => '[user]', 'ns2:Password' => '[pass]'), SOAP_ENC_OBJECT);
    $header = new SoapHeader($secure.'/BisnodeWebService', 'AuthHeader', $auth);
    
    $soapClient->__setSoapHeaders($header);
    
    $result = $soapClient->GetData_PodjetjeReport(array('sMSorDS' => '1234567'));
    
    echo "====== REQUEST HEADERS =====" . PHP_EOL;
    var_dump($soapClient->__getLastRequestHeaders());
    
    echo "========= REQUEST ==========" . PHP_EOL;
    var_dump($soapClient->__getLastRequest());
    
    echo "========= RESPONSE ==========" . PHP_EOL;
    var_dump($result);
    

    标题结果:

    ========= REQUEST ==========
    <?xml version="1.0" encoding="UTF-8"?>
    <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://servisi.gvin.com/BisnodeWebService" xmlns:ns2="https://servisi.bisnode.si/BisnodeWebService">
        <SOAP-ENV:Header>
            <ns2:AuthHeader>
                <ns2:Username>[user]</ns2:Username>
                <ns2:Password>[pass]</ns2:Password>
            </ns2:AuthHeader>
        </SOAP-ENV:Header>
        <SOAP-ENV:Body>
            <ns1:GetData_PodjetjeReport>
                <ns1:sMSorDS>1234567</ns1:sMSorDS>
            </ns1:GetData_PodjetjeReport>
        </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-02
      • 1970-01-01
      • 1970-01-01
      • 2023-03-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多