zandbelt / php-ws-trust-client

WS-Trust Client functionality & samples in PHP
Apache License 2.0
9 stars 2 forks source link

Decry-pt Token #1

Open mohammedabualsoud opened 7 years ago

mohammedabualsoud commented 7 years ago

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

CN=*.myorg.com DUMMY VLAUE DUMMY VALUE DUMMY VALUE

Any help appreciated, Thanks

zandbelt commented 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

mohammedabualsoud commented 7 years ago

@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.

zandbelt commented 7 years ago

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.

mohammedabualsoud commented 7 years ago

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.

zandbelt commented 7 years ago

Who/what is the STS and what does the RST look like in detail?

mohammedabualsoud commented 7 years ago

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";
zandbelt commented 7 years ago

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

mohammedabualsoud commented 7 years ago

the $token value is null why do you think that?

zandbelt commented 7 years ago

if the $token value is null, it means that the client could not even decode the XML response; can you paste it?

mohammedabualsoud commented 7 years ago

Attached response from adfs/services/trust/13/UsernameMixed: ` http://docs.oasis-open.org/ws-sx/ws-trust/200512/RSTRC/IssueFinal</a:Action>

2016-11-01T09:25:24.400Z 2016-11-01T09:30:24.400Z 2016-11-01T09:25:24.400Z 2016-11-01T17:25:24.400Z https://dummy.com:5443/ CN=*.DUMMY.com DUMMY DUMMY DUMMY dummy dummy http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0 http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer `
mohammedabualsoud commented 7 years ago

@zandbelt This call cause the problem I think. $token = $xpath->query('wsse:BinarySecurityToken', $token);

zandbelt commented 7 years ago

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

mohammedabualsoud commented 7 years ago

The $token value are before the $xpath->query(..) call are as follow :

DOMElement Object

mohammedabualsoud commented 7 years ago

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

mohammedabualsoud commented 7 years ago

@zandbelt after calling parseRSTR method I got the correct token DOM element, the problem occurs after calling $xpath->query('wsse:BinarySecurityToken', $token) statement.

zandbelt commented 7 years ago

Where did you get that code from?

mohammedabualsoud commented 7 years ago

I modified the client.php from salesforce directory

zandbelt commented 7 years ago

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)
);
mohammedabualsoud commented 7 years ago

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.

mohammedabualsoud commented 7 years ago

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>

zandbelt commented 7 years ago

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

mohammedabualsoud commented 7 years ago

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?