I am getting an error while trying to send a soap request (soapCall) to the server.
Fatal error: Uncaught SoapFault exception: [ns1:InvalidSecurity] An error was discovered processing the <wsse:Security> header
I need to send the ws-security header
<wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken wsu:Id="UsernameToken-1" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:Username>userID</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">passwd</wsse:Password>
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">ZTQ3YmJjZmM1ZTU5ODg3YQ==</wsse:Nonce>
<wsu:Created>2013-07-05T19:55:36.458Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
After a lot of research I think the issue I got is the nonce didnt meet the requirement. As I am making up the soap header looks like the example I got. The only unknown element is to calculating this nonce...
From the example nonce I got, its a set of 24 numbers + alphabet + special character
Something like this
ZTQ3YmJjZmM1ZTU5ODg3YQ==
But however, I am not too sure how do you calculate the wsse nonce from php...is there any standard?
the code I had
$nonce = sha1(mt_rand());
Result
dabddf9dbd95b490ace429f7ad6b55c3418cdd58
which is something completely different than the example...and I believe this is the reason why this code is not working.
So I am doing more research and now I am using this
$NASC = substr(md5(uniqid('the_password_i_am _using', true)), 0, 16);
$nonce = base64_encode($NASC);
Result
NzJlMDQ4OTAyZWIxYWU5ZA==
Now, it looks similar to the example but I still getting that error showed from the beginning.
Can someone give me a hand please?
some further testing with soapUI.
same userID and passwd, set the passwordtype to passwordtext
and it is working.
is anyone know how do the soapUI calculate the nonce? or have any idea how soapUI passing the ws-security?
Two optional elements are introduced in the <wsse:UsernameToken> element to provide a countermeasure for replay attacks: <wsse:Nonce> and <wsu:Created>. A nonce is a random value that the sender creates to include in each UsernameToken that it sends.
The basic premise of WSSE is that a request header is checked for encrypted credentials, verified using a timestamp and nonce, and authenticated for the requested user using a password digest. It is implemented by the OroWsseAuthenticationBundle that covers most cases from the WSSE specification (PDF).
The WSSE security header contains authentication information so the web service provider can authenticate the PowerCenter Integration Service. WSSE security header also works with basic, digest, and NTLM authentication types.
A WS-Security UsernameToken enables an end-user identity to be passed over multiple hops before reaching the destination web service. The user identity is inserted into the message and is available for processing at each hop on its path.
try something like this
string usn = "MyUsername";
string pwd = "MyPassword";
DateTime created = DateTime.Now.ToUniversalTime();
var nonce = getNonce();
string nonceToSend = Convert.ToBase64String(Encoding.UTF8.GetBytes(nonce));
string createdStr = created.ToString("yyyy-MM-ddTHH:mm:ssZ");
string passwordToSend = GetSHA1String(nonce + createdStr + pwd);
and functions:
protected string getNonce()
{
string phrase = Guid.NewGuid().ToString();
return phrase;
}
protected string GetSHA1String(string phrase)
{
SHA1CryptoServiceProvider sha1Hasher = new SHA1CryptoServiceProvider();
byte[] hashedDataBytes = sha1Hasher.ComputeHash(Encoding.UTF8.GetBytes(phrase));
string test = Convert.ToString(hashedDataBytes);
return Convert.ToBase64String(hashedDataBytes);
}
As uniqid()
is based on a Pseudo-Random Number Generator, it does not provide enough entropy. Siehe Insufficient Entropy For Random Values
$nonce = base64_encode( bin2hex( openssl_random_pseudo_bytes( 16 ) ) );
If you don't have the OpenSSL module try this fallback to mcrypt_create_iv()
see:
https://github.com/padraic/SecurityMultiTool/blob/master/library/SecurityMultiTool/Random/Generator.php
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With