Open mohammedabualsoud opened 7 years ago
You'll need to provide the file path to the private key to decrypt the assertion as shown in https://github.com/zandbelt/php-ws-trust-client/blob/master/msinterop/exercise1.php#L58
@zandbelt So I have to get the private key from the STS by an email or some secure way right ?
Thank you for your fast response.
No, the assertion should be encrypted with a public key that is associated with a private key that the receiver already has. You'd configure the STS to use the receivers's public key to encrypt the assertion.
Sorry I don't get it. Let me explain my scenario because I don't know what you mean by the receiver here.
I have a client application that create a RST request using bearer token and I have provided the credential within the soap header to authenticate the client, then I got the RSTR message response that include an encrypted token same as above response. I see that I need to decrypt the token in order to get it and append it with every request to the SP which is a CRM app.
Thanks a lot.
Who/what is the STS and what does the RST look like in detail?
Ok, The STS(secruity token service) is an ADFS 3.0. The RST(Request Security Token) is a samel bearer token message attached :
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
<s:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="_0">
<wsu:Created>2016-10-31T09:13:12Z</wsu:Created>
<wsu:Expires>2016-10-31T09:18:12Z</wsu:Expires>
</wsu:Timestamp>
<wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="Me">
<wsse:Username>username</wsse:Username>
<wsse:Password>password</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
<wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">https://org.com/adfs/services/trust/13/UsernameMixed</wsa:To>
<wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Issue</wsa:Action>
</s:Header>
<s:Body>
<wst:RequestSecurityToken xmlns:wst="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
<wst:TokenType>http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0</wst:TokenType>
<wst:RequestType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue</wst:RequestType>
<wsp:AppliesTo xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
<wsa:EndpointReference xmlns:wsa="http://www.w3.org/2005/08/addressing">
<wsa:Address>https:org.com</wsa:Address>
</wsa:EndpointReference>
</wsp:AppliesTo>
<wst:KeyType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer</wst:KeyType>
</wst:RequestSecurityToken>
</s:Body>
</s:Envelope>
Code :
// RST appliesTo
$appliesTo = 'crm.com';
// PingFederate 6.x/7.x IP-STS endpoint
$IPSTS = 'adfsorg.com/adfs/services/trust/13/UsernameMixed';
// special token type (needs to be enabled in run.properties)
$tokenType = WSTRUST::TOKENTYPE_SAML20;
// call to IP-STS, authenticate with uname/pwd, retrieve RSTR with generated token
$result = HTTP::doSOAP(
$IPSTS,
WSTRUST::getRSTHeader(
WSTRUST::getUserNameToken($username, $password),
WSTRUST::getTimestampHeader(), $IPSTS),
WSTRUST::getRST($tokenType, $appliesTo)
);
// parse the RSTR that is returned
list($dom, $xpath, $token, $proofKey) = WSTRUST::parseRSTR($result);
// retrieve the actual token contents from the RSTR
// NB: it is a SAML Response+Assertion in base64-encoded format embedded in a BinaryToken
$token = $xpath->query('wsse:BinarySecurityToken', $token);
$token = $token->item(0)->textContent;
print " # SAML 2.0 Token:\n\n" . base64_decode($token) . "\n";
it looks like this assertion was then encrypted with the public key of the CRM application and your client just needs to pass the encrypted assertion as a whole to the CRM app
the $token value is null why do you think that?
if the $token value is null, it means that the client could not even decode the XML response; can you paste it?
Attached response from adfs/services/trust/13/UsernameMixed:
`
@zandbelt This call cause the problem I think. $token = $xpath->query('wsse:BinarySecurityToken', $token);
this line: https://github.com/zandbelt/php-ws-trust-client/blob/master/wstrust.php#L54 probably needs to change because there's only a single RequestedSecurityToken in the response, not a collection, which is different from ADFS 2.0
edit: that seemed to be a markup issue only
The $token value are before the $xpath->query(..) call are as follow :
DOMElement Object
Ok, I will make a research how to did that.
When I got the token I have to attached it with every request to the CRM (SP) without need to decrypt it right or I have to test. This whole topic really bad documented over internet I'm struggle with this ADFS active authentication.
Thank you very much M.R
@zandbelt after calling parseRSTR method I got the correct token DOM element, the problem occurs after calling $xpath->query('wsse:BinarySecurityToken', $token) statement.
Where did you get that code from?
I modified the client.php from salesforce directory
The BinarySecurityToken returned in that code is specific to Salesforce; in your case you get back an encrypted SAML assertion; you should be able to pass it on with something like:
// parse the RSTR that is returned
list($dom, $xpath, $token, $proofKey) = WSTRUST::parseRSTR($result);
$xpath->registerNamespace('saml', 'urn:oasis:names:tc:SAML:2.0:assertion');
$token = $xpath->query('saml:EncryptedAssertion', $token);
$token = $token->item(0);
// now pass the encrypted assertion to the RP
$ts = WSTRUST::getTimestampHeader('_0');
$token = $dom->saveXML($token);
$result = HTTP::doSOAP(
$targetRPSTS,
WSTRUST::getRSTHeader($token, $ts, $targetRPSTS),
WSTRUST::getRST($tokenTypeRPSTS, $appliesToRPSTS)
);
so when I got the encrypted assertion I need to send it to the SP STS ? In my case the SP is a CRM app. From where I can get the SP STS I thought I just need to include the bearer token to the CRM app and it handle everything.
I don't know if I apply the flow correct I first got the token from adfs then I sent the assertion to the adfs in order to validate the token and it give me the following response:
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing"> <s:Header> <a:Action s:mustUnderstand="1">http://www.w3.org/2005/08/addressing/soap/fault</a:Action> </s:Header> <s:Body> <s:Fault> <s:Code> <s:Value>s:Sender</s:Value> <s:Subcode> <s:Value xmlns:a="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">a:InvalidSecurityToken</s:Value> </s:Subcode> </s:Code> <s:Reason> <s:Text xml:lang="en-US">An error occurred when processing the security tokens in the message.</s:Text> </s:Reason> </s:Fault> </s:Body> </s:Envelope>
why would you retrieve the token and validate it at the same ADFS server? you need to find out what your CRM app supports in terms of token handling / STS functions
Ok that's make sense but what if the CRM app are deployed internally on same network that ADFS installed on?
the STS component are usually separated from the application right?
I want to ask you what do I need to decry-pt the token when it's encrypted.
Here's a sample of what I got it's a samel2.0 token
Any help appreciated, Thanks