15
votes

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?

4
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
@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
I've sent you an email. Did you get it?woloski
Yes, I have, I will send you the trace tomorrow ;-)jwillmer

4 Answers

6
votes

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 :-)

9
votes

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

4
votes

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.

0
votes

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