Как мне аутентифицировать пользователей с помощью SOAP?
Должен ли я потребовать, чтобы пользователь отправил свое имя пользователя и пароль с каждым запросом SOAP, и я аутентифицирую его против базы данных?
Разве это не вызывает ненужных запросов?
Как мне аутентифицировать пользователей с помощью SOAP?
Должен ли я потребовать, чтобы пользователь отправил свое имя пользователя и пароль с каждым запросом SOAP, и я аутентифицирую его против базы данных?
Разве это не вызывает ненужных запросов?
Простым способом было бы аутентификацию в первом запросе, создать запись сеанса на стороне сервера, содержащую удаленный IP-адрес, и токен, который вы передаете клиенту как authToken. Затем попросите клиента передать это authToken в будущих запросах. Этот authToken должен соответствовать внутренним данным сеанса, которые вы храните о клиенте, но позволит вам избежать необходимости совершать круговые поездки в базу данных только для проверки подлинности.
Тем не менее, @Marcus Adams имеет хорошую точку зрения относительно апатии. Есть люди, которые выталкивают всевозможные модели безопасности SOAP. WS-Security - это текущее состояние техники. Все они работают, помещая данные аутентификации в заголовок SOAP. В конце концов, почему SOAP-сообщение содержит как заголовок, так и bodypart.
Когда пользователь отправляет имя пользователя и пароль с каждым запросом, это способ, которым я видел большинство интерфейсов SOAP. На самом деле, я не видел никакой другой реализации, кроме идеи API-ключа, которая просто торгует Username и Password для другого токена.
Интерфейсы SOAP должны быть безстоящими, например HTTP, поэтому это кажется нормальным следствием.
Определите пользовательский заголовок SOAP и обменитесь идентификаторами аутентификации в заголовке. Чтение значений из заголовка и аутентификация.
Вот простой пример того, как я использую проверку API в заголовке:
файл портфолио-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>';
}
?>
файл портфолио-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();
?>
файл портфолио-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>