12

的内置PHP扩展SOAP不会验证传入SOAP请求中的所有内容XML SchemaWSDL. 它确实会检查基本实体的存在,但是当你有一些复杂的东西比如simpleType限制时,扩展几乎会忽略它们的存在。

验证包含在中的SOAP请求的最佳方法是什么?XML SchemaWSDL

4

6 回答 6

4

除了原生 PHP5 SOAP 库之外,我还可以告诉您,目前 PEAR 和 Zend SOAP 库都不会对消息进行模式验证。(不幸的是,我不知道有任何 PHP SOAP 实现。)

我要做的是将 XML 消息加载到DOMDocument对象中,并使用 DOMDocument 的方法来验证架构。

于 2008-09-30T08:53:22.520 回答
3

在这个问题上一直在挖掘一个视图时间。本机 PHP SoapServer 和 NuSOAP 库都不进行任何验证。PHP SoapServer 只是进行类型转换。例如,如果您定义

<xsd:element name="SomeParameter" type="xsd:boolean" />

并提交

<get:SomeParameter>dfgdfg</get:SomeParameter>

你会得到 php 类型 boolean (true)

尽管 NuSOAP 识别简单类型,但它只是将所有内容转换为字符串:

从 nuSOAP 调试日志:

nusoap_xmlschema: processing typed element SomeParameter of type http://www.w3.org/2001/XMLSchema:boolean

所以最好的方法是 joelhardi 解决方案来验证自己或使用一些 xml 解析器,如 XERCES

于 2011-12-16T09:55:50.490 回答
2

通常不会根据 WSDL 进行验证。如果 WSDL 设计正确,则应该有一个底层 xml 模式 (XSD) 来验证请求的正文。您的 XML 解析器应该能够做到这一点。

其余的取决于您如何实现 Web 服务以及您使用的 SOAP 引擎。我不直接熟悉 PHP 引擎。对于 WSDL/接口级别的“验证”,我通常会这样做:

  1. 请求的主体是否与已知的请求类型匹配并且它是否有效(通过 XSD)?
  2. 该消息在这种情况下是否有意义,我可以将其映射到操作/处理程序吗?
  3. 如果是这样,开始处理它
  4. 否则:错误
于 2008-09-20T15:43:06.687 回答
2

使用本机 SoapServer PHP有点棘手,但也可以:

function validate(string $xmlEnvelope, string $wsdl) : ?array{
    
    libxml_use_internal_errors(true);
    
     //extracting schema from WSDL
    $xml = new DOMDocument();
    $wsdl_string = file_get_contents($wsdl);

    //extracting namespaces from WSDL
    $outer = new SimpleXMLElement($wsdl_string);
    $wsdl_namespaces = $outer->getDocNamespaces();
    
    //extracting the schema tag inside WSDL
    $xml->loadXML($wsdl_string);
    $xpath = new DOMXPath($xml);
    $xpath->registerNamespace('xsd', 'http://www.w3.org/2001/XMLSchema');
    $schemaNode = $xpath->evaluate('//xsd:schema');

    $schemaXML = "";
    foreach ($schemaNode as $node) {
        
        //add namespaces from WSDL to schema
        foreach($wsdl_namespaces as $prefix => $ns){
            $node->setAttribute("xmlns:$prefix", $ns);
        }
        $schemaXML .= simplexml_import_dom($node)
                ->asXML();
    }
    
    //capturing de XML envelope
    $xml = new DOMDocument();
    $xml->loadXML($xmlEnvelope);
    
    //extracting namespaces from soap Envelope
    $outer = new SimpleXMLElement($xmlEnvelope);
    $envelope_namespaces = $outer->getDocNamespaces();
       
    $xpath = new DOMXPath($xml);
    $xpath->registerNamespace('soapEnv', 'http://schemas.xmlsoap.org/soap/envelope/');
    $envelopeBody = $xpath->evaluate('//soapEnv:Body/*[1]');
    $envelopeBodyXML = "";
    foreach ($envelopeBody as $node) {
 
        //add namespaces from envelope to the body content
        foreach($envelope_namespaces as $prefix => $ns){
            $node->setAttribute("xmlns:$prefix", $ns);
        }
        $envelopeBodyXML .= simplexml_import_dom($node)
                ->asXML();
    }
    
    $doc = new DOMDocument();
    $doc->loadXML($envelopeBodyXML); // load xml
    $is_valid_xml = $doc->schemaValidateSource($schemaXML); // path to xsd file

    return libxml_get_errors();   
      
}

在您的 SoapServer 函数实现中:

function myFunction($param) {

    $xmlEnvelope = file_get_contents("php://input");
    $errors = validate($xmlEnvelope, $wsdl);

}
于 2022-01-17T17:02:49.840 回答
-1

我找不到任何简单的方法来执行验证,最终在业务逻辑中有验证代码。

于 2009-02-16T21:42:02.970 回答
-3

前段时间,我使用NuSOAP创建了一个使用 PHP 的概念验证Web 服务。我不知道它是否验证了输入,但我认为它确实如此。

于 2008-09-21T07:03:29.453 回答