1

http://www.whitemesa.com/soapauth.htmlで概説されているように、基本認証クレデンシャルを受け入れるPHPSOAPサービスを作成しました。これは、インスタンスBasicAuthのハンドラークラス内にメソッドを定義することで行いました。SOAPServerこれはすべて正常に機能します。

ただし、何らかの理由で認証が失敗した場合(ユーザー名が正しくない、リクエストにヘッダーがない)、次のように応答にヘッダーBasicAuthを含めたいと思います。BasicChallenge

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
   <SOAP-ENV:Header>
      <h:BasicChallenge xmlns:h="http://soap-authentication.org/basic/2001/10/"
                        SOAP-ENV:mustUnderstand="1">
         <Realm>Realm</Realm>
      </h:BasicChallenge>
   </SOAP-ENV:Header>
   <SOAP-ENV:Body>
      <SOAP-ENV:Fault>
         <faultcode>SOAP-ENV:Client</faultcode>
         <faultstring>Authentication failed</faultstring>
      </SOAP-ENV:Fault>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

次のコードは機能しません(ヘッダーは応答に追加されません)。

$soapServer->addSoapHeader(new SoapHeader("http://soap-authentication.org/basic/2001/10/", "BasicChallenge", array("Realm" => "Realm"), true));
throw new SoapFault("Client", "Authentication Failed");

$soapServer->fault()代わりに電話throw new SoapFaultしても違いはありません。

自分でFaultオブジェクトを作成し、それを通常の応答として返すことを試みましたが、PHPに整形式の応答を送信させることができませんでした。

前もって感謝します。

4

1 に答える 1

0

これは2013年でしたが、実際にはまったく同じ問題があります。さて、それは2019年であり、PHPの現在のバージョンは7.3であり、7.4は大きな一歩を踏み出しました。残念ながら、SoapServerクラスは、SoapFaultの場合にsoapヘッダーを完全に無視します。

私はsoapサーバーのXML応答を操作するための小さな回避策を書きました。同じ問題を抱えているすべての人のために、ここに小さな例、それを解決する方法があります。

1.SoapServerを初期化します

$server = new SoapServer($wsdl, $options);

ob_start();
$server->setObject($service);
$server->handle();
$response = ob_get_contents();
ob_end_clean();

実際には、単純な初期化を行っています。単純にコンテンツを返す代わりに、出力バッファリング関数を使用してxml応答をインターセプトします。の結果は、のxml文字列です$response

2.応答が障害であるかどうかを確認します

SoapServer有効な応答である場合、実際にはクラスは石鹸ヘッダーを追加しています。応答が障害であるかどうかを確認する必要があります。

$doc = new DOMDocument();
$doc->loadXML($response);

$xpath = new DOMXPath($doc);
$isFault = $xpath->query('//*[local-name()="Fault"]')->length;

応答xml文字列をDOMDocumentクラスにロードするだけです。これからは、DOM関数を使用してxml要素にアクセスできるようになります。より良い取り扱いのために、私はDOMXPathクラスを使用しています。もちろん、DOMDocumentクラスを使用してXMLノードを判別することもできます。この$isFault変数は、次のステップに役立ちます。

3.障害が発生した場合は、石鹸ヘッダーを設定します

残念ながらaddSoapHeader、soapヘッダーを設定するだけの便利な機能はありません。この場合、手動で行う必要があります。

if ($isFault) {
    $header = $doc->createElementNS('http://schemas.xmlsoap.org/soap/envelope/', 'Header');
    $body = $doc->getElementsByTagNameNS('http://schemas.xmlsoap.org/soap/envelope/', 'Body')->item(0);

    $realm = $doc->createElementNS('http://soap-authentication.org/basic/2001/10/', 'h:Realm');
    $basicChallenge = $doc->createElementNS('http://soap-authentication.org/basic/2001/10/', 'h:BasicChallenge');

    $basicChallenge->appendChild($realm);
    $header->appendChild($basicChallenge);

    $doc->documentElement->insertBefore($header, $body);
}

$xmlResponse = $doc->saveXML($doc->documentElement);

header('Content-Length: ' . strlen($xmlResponse));
echo $xmlResponse;
exit();

障害の場合、ヘッダー要素を作成し、必要なすべての子ノードを追加します。すべてが追加された場合は、本文の前にヘッダーを挿入し、新しいxml構造を文字列に保存してエコーします。

これが少し役立つことを願っています。

于 2019-08-27T14:56:40.727 に答える