15

I try to connect to a SharePoint Online instance via a WPF application. I have found this article that discribes a possible solution but the problem is that the specific instance has a Active Directory Federation Services (ADFS) in front and I don't know how to get the auth-token. (I can't create a certificate for my application to authentificate against the adfs.)

Anyone who have already done this and can support me with some code snippets?

dnord
  • 1,702
  • 2
  • 18
  • 34
jwillmer
  • 3,570
  • 5
  • 37
  • 73
  • I haven't done this but I might be able to help. Can you post somewhere a Fiddler trace extracted from a regular web-based login to Office 365 using ADFS? – woloski Jul 23 '12 at 13:48
  • @woloski I can't post this because of the company informations in the trace. I could mail it to you if you give me your address. (You can find mine in my profile( – jwillmer Jul 23 '12 at 16:33
  • I've sent you an email. Did you get it? – woloski Jul 24 '12 at 17:49
  • Yes, I have, I will send you the trace tomorrow ;-) – jwillmer Jul 24 '12 at 22:02

4 Answers4

9

I've played with Fiddler. Basically the flow goes like this:

  • Get a SAML token from ADFS
  • Post it to https://login.microsoftonline.com/login.srf (body should be wa=wsignin1.0, wresult=<requestsecuritytokenresponse>…token…</rstr> and wctx=MEST=0&LoginOptions=2&wa=wsignin1%2E0&rpsnv=2&ct=1343219880&rver=6%2E1%2E6206%2E0&wp=MBI&wreply=https%3A%2F%2Fspirit365%2Esharepoint%2Ecom%2F%5Fforms%2Fdefault%2Easpx&id=500046&cbcxt=mai&wlidp=1&guest=1&vv=910&mkt=EN-US&lc=1033&bk=1343219930
  • Capture the input hidden named "t" from the Form
  • POST that "t" to /_layouts/Authenticate.aspx. That should give you the FedAuth and rtFa cookie.

From that point this is the same as the code here: http://www.wictorwilen.se/Post/How-to-do-active-authentication-to-Office-365-and-SharePoint-Online.aspx

woloski
  • 2,863
  • 16
  • 14
  • I've heard that the purpose of rtFa cookies is to make log out. How would I do that? Attach rtFa to HTTP-request and send it to any SharePoint web service? – surlac Oct 03 '12 at 13:58
6

I have found the solution and made a post about it. I also put it on github. You can find my blog post along with the github link at my blog.

I hope this helps you as much as it helped me :-)

jwillmer
  • 3,570
  • 5
  • 37
  • 73
  • Can you post this again, please? – retrography Mar 18 '15 at 22:17
  • 1
    @retrography Blog is down for maintenance but I added the GitHub link to my post. If you still need the blog post write me an email and I send it to you ;-) – jwillmer Mar 19 '15 at 06:29
  • @jwillmer from what I can see your code work's for Windows 8, but how about Window 10? I did try to test it but it didn't work for Win10. – Ionut May 08 '18 at 08:12
4

I spent a lot of time to finally figure that out. In order to get the binary Token you need to post a message in the following format to the Microsoft Online Security Token Service (STS) site URL:

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
  <s:Header>
    <a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue</a:Action>
    <a:ReplyTo>
      <a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
    </a:ReplyTo>
    <a:To s:mustUnderstand="1">[toUrl]</a:To>
    <o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
      [assertion]
    </o:Security>
  </s:Header>
  <s:Body>
    <t:RequestSecurityToken xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust">
      <wsp:AppliesTo xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
        <a:EndpointReference>
          <a:Address>[url]</a:Address>
        </a:EndpointReference>
      </wsp:AppliesTo>
      <t:KeyType>http://schemas.xmlsoap.org/ws/2005/05/identity/NoProofKey</t:KeyType>
      <t:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</t:RequestType>
      <t:TokenType>urn:oasis:names:tc:SAML:1.0:assertion</t:TokenType>
    </t:RequestSecurityToken>
  </s:Body>
</s:Envelope>

This message is needed to replace the tokens with the following values:

[toUrl]: Microsoft Online Security Token Service (STS) site URL.
[url]: Your SP site URL
[assertion]: Is assertion XLM token you have got from your Federation service.

After you get the t=... binary token from the response XML, you can post that to your SP default.aspx in order to get cookies.

honk
  • 9,137
  • 11
  • 75
  • 83
Ali Alemi
  • 41
  • 1
  • I have tried this approach, and getting the Fedauth cookies, but when i am redirecting to the SharePoint online site then its again asking for user credentials. and if i am making a host entry as "testO365.sharpoint.com" in my local then its working fine, any suggestion. – SHAURAJ SINGH Mar 14 '17 at 13:45
  • Hy, i know it is an old post. but maybe someone can help me tough. I managed to get the assertion xml from our adfs-server. But if I copy it (the and anything inside) into the xml as stated i get always the error stating "websso invalid assertion" (btw. I post to (https://login.microsoftonline.com/extsts.srf) – Leopold Lerch Jun 22 '17 at 11:16
  • Help: Where do you the place the code into? I'm using C# but I don't understand where that gets placed and called from. – Goku Jun 18 '21 at 15:37
0

For anyone with trouble (its really tough), here is some clarrification

The 4 steps are 1)get the assertion from your SAML IDP 2)trade the assertion for a STS token 3)trade the STS token for cookies 4)use the cookies to do your rest call

For step 1, I have ping federate. Use this in postman to post to your token id processor to get an assertion: POST https://pingfederate/idp/sts.wst?TokenProcessorId=username

<s:Envelope xmlns:s='http://www.w3.org/2003/05/soap-envelope' xmlns:a='http://www.w3.org/2005/08/addressing' xmlns:u='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd'>
    <s:Header>
        <a:Action s:mustUnderstand='1'>http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue</a:Action>
        <a:ReplyTo>
            <a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
        </a:ReplyTo>
        <o:Security s:mustUnderstand='1' xmlns:o='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd'>
            <o:UsernameToken>
                <o:Username>yourusername</o:Username>
                <o:Password>yourpass</o:Password>
            </o:UsernameToken>
        </o:Security>
    </s:Header>
    <s:Body>
        <t:RequestSecurityToken xmlns:t='http://schemas.xmlsoap.org/ws/2005/02/trust'>
            <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>urn:federation:MicrosoftOnline</wsa:Address>
                </wsa:EndpointReference>
            </wsp:AppliesTo>
            <t:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</t:RequestType>
        </t:RequestSecurityToken>
    </s:Body>
</s:Envelope>

It will generate an envelope with the assertion in it. Make sure to copy it in raw format (not pretty xml). Everything from the <saml:Assertion to /saml:Assertion>

For step 2, when you POST to https://login.microsoftonline.com/extSTS.srf, make sure the assertion is pasted in raw format (not pretty XML).

Use:

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
  <s:Header>
    <a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue</a:Action>
    <a:ReplyTo>
      <a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
    </a:ReplyTo>
    <o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
      <saml:Assertion AssertionID="hp4CtHjK_lL" Issue Instant...................../ds:Signature></saml:Assertion>
    </o:Security>
  </s:Header>
  <s:Body>
    <t:RequestSecurityToken xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust">
      <wsp:AppliesTo xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
        <a:EndpointReference>
          <a:Address>https://myshare.sharepoint.com/sites/mysite</a:Address>
        </a:EndpointReference>
      </wsp:AppliesTo>
      <t:KeyType>http://schemas.xmlsoap.org/ws/2005/05/identity/NoProofKey</t:KeyType>
      <t:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</t:RequestType>
      <t:TokenType>urn:oasis:names:tc:SAML:1.0:assertion</t:TokenType>
    </t:RequestSecurityToken>
  </s:Body>
</s:Envelope>

For step 3, POST to https://myshare.sharepoint.com/_forms/default.aspx?wa=wsignin1.0 and make sure you have the User-Agent be a regular user agent like Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0). In the body of the post, its going to be everything in the <BinarySecurityToken that was generated by step 2, so something like t=EwDgAk6hBwAUu3......................... Thats the entire body, nothing else. It will generate some cookies. One is for myshare.sharepoint.com called FedAuth, and another is sharepoint.com rtFa

Step 4, Once you get the cookies, you can GET your sharepoint list

https://myshare.sharepoint.com/sites/mysite/_api/Web/Lists/GetByTitle('Updating%20List%E2%80%8B')/items