I'm trying to implement WSSE authentication on a Web Services API. I followed this tutorial on symfony official site. I send requests with SoapUI, with security headers :
POST http://dev.sellerphp.com/app_dev.php/wsapi/soap/ordersfollowup HTTP/1.0
Accept-Encoding: gzip,deflate
Content-Type: text/xml;charset=UTF-8
SOAPAction: "http://dev.sellerphp.com/app_dev.php/wsapi/soap/ordersfollowup"
Content-Length: 1520
Host: dev.sellerphp.com
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
<soapenv:Envelope xmlns:ord="https://dev.sellerphp.com/app_dev.php/wsapi/soap/ordersfollowup?wsdl" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsap="http://wsapi.sellerphp.com/">
<soapenv:Header>
<wsse:Security soap:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsu:Timestamp wsu:Id="TS-14">
<wsu:Created>2012-10-10T09:36:10Z</wsu:Created>
<wsu:Expires>2012-10-10T09:52:50Z</wsu:Expires>
</wsu:Timestamp>
<wsse:UsernameToken wsu:Id="UsernameToken-13">
<wsse:Username>myUsername</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">hb5AJ7CT2tMSQymSsxwvc8J/xoI=</wsse:Password>
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">PEo//Z/yGF5/HCW6rkCuwQ==</wsse:Nonce>
<wsu:Created>2012-10-10T09:36:10.485Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<wsap:setTracking>
<input>
<!--1 to 10 repetitions:-->
<OrderItemTracking>
<order-item-id>?</order-item-id>
<tracking-number>?</tracking-number>
</OrderItemTracking>
</input>
</wsap:setTracking>
</soapenv:Body>
</soapenv:Envelope>
On the server-side, the WsseListener class doesn't read SOAP headers... The example only involves that headers are defined on the Request level, but they are only embedded in SOAP envelope :
public function handle(GetResponseEvent $event)
{
$request = $event->getRequest();
$wsseRegex = '/UsernameToken Username="([^"]+)", PasswordDigest="([^"]+)", Nonce="([^"]+)", Created="([^"]+)"/';
if (!$request->headers->has('x-wsse') || 1 !== preg_match($wsseRegex, $request->headers->get('x-wsse'), $matches))
{
return;
}
// ########### It never reached this line, never found any headers...
var_dump($matches);exit;
$token = new WsseUserToken();
$token->setUser($matches[1]);
$token->digest = $matches[2];
$token->nonce = $matches[3];
$token->created = $matches[4];
try
{
$authToken = $this->authenticationManager->authenticate($token);
$this->securityContext->setToken($authToken);
}
catch (AuthenticationException $failed)
{
// ... you might log something here
// To deny the authentication clear the token. This will redirect to the login page.
// $this->securityContext->setToken(null);
// return;
// Deny authentication with a '403 Forbidden' HTTP response
$response = new Response();
$response->setStatusCode(403);
$event->setResponse($response);
}
}
I don't know how to read soap:Header headers from the listener. Can you help me ?