How to do authentication using SOAP?

后端 未结 4 1072
夕颜
夕颜 2020-12-30 06:47

How do I authenticate users with SOAP?

Will I have to require the user to send his username and password with every SOAP request and I authenticate him against the d

相关标签:
4条回答
  • 2020-12-30 06:49

    Here's a simple example of how I use an API validation in the header:

    file portfolio-lookup-client.php

    <?php
    ini_set("soap.wsdl_cache_enabled", "0"); // disabling WSDL cache
    class portfolioLookupAuth 
    { 
        public $apiKey; 
        public function __construct($key) 
        { 
            $this->apiKey = $key; 
        } 
    } 
    $apiKey = "123456"; 
    $url = 'http://mysite.com/php5soap/portfolio-lookup.wsdl';
    $client = new SoapClient($url, array("trace" => 1, "exception" => 0)); 
    
    // Create the header 
    $auth  = new portfolioLookupAuth($apiKey); 
    // SoapHeader::__construct ( string $namespace , string $name [, mixed $data [, bool $mustunderstand [, string $actor ]]] ) 
    $header = new SoapHeader($url, "APIValidate", $auth, false);   
    
      try {
    
        $result = $client->__soapCall("getPortfolioByName", array("portfolioName" => "WQAM"), NULL, $header);       
        print_r($result);
    
        print "<pre>\n"; print "Request :\n".htmlspecialchars($client->__getLastRequest()) ."\n";
        print "Response:\n".htmlspecialchars($client->__getLastResponse())."\n"; print "</pre>";    
    
      } catch (SoapFault $exception) {
    
        echo 'Exception Thrown: '.$exception->faultstring.'<br><br>';  
    
      }
    
    ?>
    

    file portfolio-lookup-server.php

    <?php
    ini_set("soap.wsdl_cache_enabled", "0"); // disabling WSDL cache
    
    class PortfolioLookupService {
    
        private $apiKey = '123456';
    
        private $portfolios = array(
                'WPOW' => 'Power 96 party station.',
                'WQAM' => 'Sports radio site.',
                'WJBR' => 'Cool sites for bands.',
                'WKIS' => 'Kiss Country 2',
    
      );
    
      public function APIValidate($auth){
    
        if($auth->apiKey != $this->apiKey){
            throw new SoapFault("Server", "Incorrect key");
        }
    
      }
    
      function getPortfolioByName($portfolioName) {
        //print_r($portfolioName); exit();
        if (isset($this->portfolios[$portfolioName])) {
          return $this->portfolios[$portfolioName];
        } else {
          return 'Portfolio name "'.$portfolioName.'" not found.';
          //throw new SoapFault('code', 'string', 'actor', 'detail', 'name', 'header');
          throw new SoapFault("Server","Unknown Name '$portfolioName'.");      
        }
      }  
    
      function getPortfoliosAll() {
          return $this->portfolios;
      }    
    
    }
    
    $server = new SoapServer("portfolio-lookup.wsdl");
    $server->setClass("PortfolioLookupService");
    $server->handle();
    
    ?>
    

    file portfolio-lookup.wsdl

    <?xml version ='1.0' encoding ='UTF-8' ?>
    
    <definitions name='PortfolioLookup'
    
      targetNamespace='http://example.org/PortfolioLookup'
    
      xmlns:tns='PortfolioLookup'
    
      xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/'
    
      xmlns:xsd='http://www.w3.org/2001/XMLSchema'
    
      xmlns:soapenc='http://schemas.xmlsoap.org/soap/encoding/'
    
      xmlns:wsdl='http://schemas.xmlsoap.org/wsdl/'
    
      xmlns='http://schemas.xmlsoap.org/wsdl/'>
    
    <message name='getPortfolioByNameRequest'>
      <part name='portfolioName' type='xsd:string'/>
    </message>
    <message name='getPortfolioByNameResponse'>
      <part name='Result' type='xsd:string'/>
    </message>
    
    
    <message name='getPortfoliosAllRequest'>
      <part name='portfolioName' type='xsd:string'/>
    </message>
    <message name='getPortfoliosAllResponse'>
      <part name='Result' type='xsd:array'/>
    </message>
    
    
    <message name='APIValidateRequest'>
    <part name='apiKey' type='xsd:string'/>
    </message>
    <message name='APIValidateResponse'>
    <part name='testReturn' type='xsd:string'/>
    </message>
    
    
    
    <portType name='PortfolioLookupPortType'>
    
      <operation name='getPortfolioByName'>
        <input message='tns:getPortfolioByNameRequest'/>
        <output message='tns:getPortfolioByNameResponse'/>
      </operation>
    
      <operation name='getPortfoliosAll'>
        <input message='tns:getPortfoliosAllRequest'/>
        <output message='tns:getPortfoliosAllResponse'/>
      </operation>
    
        <operation name='APIValidate'>
        <input message='tns:APIValidateRequest'/>
        <output message='tns:APIValidateResponse'/>
        </operation>
    
    </portType>
    
    <binding name='PortfolioLookupBinding' type='tns:PortfolioLookupPortType'>
    
      <soap:binding style='rpc'
        transport='http://schemas.xmlsoap.org/soap/http'/>
    
    
      <operation name='getPortfolioByName'>
        <soap:operation soapAction='urn:PortfolioLookup#getPortfolioByName'/>
        <input>
          <soap:body use='encoded' namespace='urn:PortfolioLookup'
            encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>
        </input>
        <output>
          <soap:body use='encoded' namespace='urn:PortfolioLookup'
            encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>
        </output>
      </operation>
    
    
      <operation name='getPortfoliosAll'>
        <soap:operation soapAction='urn:PortfolioLookup#getPortfoliosAll'/>
        <input>
          <soap:body use='encoded' namespace='urn:PortfolioLookup'
            encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>
        </input>
        <output>
          <soap:body use='encoded' namespace='urn:PortfolioLookup'
            encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>
        </output>
      </operation>  
    
    
    
    
    </binding>
    
    <service name='PortfolioLookupService'>
    
      <port name='PortfolioLookupPort' binding='PortfolioLookupBinding'>
        <soap:address location='http://mysite.com/php5soap/portfolio-lookup-server.php'/>
      </port>
    
    </service>
    
    </definitions>
    
    0 讨论(0)
  • 2020-12-30 06:59

    Having the user send the username and password with each request is the way that I've seen most SOAP interfaces implemented. Actually, I've not seen any other implementation other than the API key idea, which is just trading a Username and Password for some other token.

    SOAP interfaces should be stateless, like HTTP, so this seems like a normal consequence.

    0 讨论(0)
  • 2020-12-30 07:04

    Define a custom SOAP header and exchange authentication credentials in the header. Read values from header and authenticate.

    0 讨论(0)
  • 2020-12-30 07:09

    An easier way would be to authenticate on the first query, build a session record on the server side containing the remote IP address and a token that you give to the client as an authToken. Then have the client pass this authToken in future queries. This authToken has to match the internal session data you keep about the client, but would allow you to avoid having to make round-trips to the database just to do authentication.

    That said, @Marcus Adams has a good point below with regard to stateless-ness. There are people out there pushing all sorts of SOAP security models. WS-Security is the current state of the art, here. They all work by putting authentication information in the SOAP header - after all, that's why a SOAP message contains both a header and a bodypart.

    0 讨论(0)
提交回复
热议问题