Remote Authentication in SharePoint Online

14,035

According to Remote Authentication in SharePoint Online Using Claims-Based Authentication and SharePoint Online authentication articles :

The Federation Authentication (FedAuth) cookie is for each top level site in SharePoint Online such as the root site, the MySite, the Admin site, and the Public site. The root Federation Authentication (rtFA) cookie is used across all of SharePoint Online. When a user visits a new top level site or another company’s page, the rtFA cookie is used to authenticate them silently without a prompt.

To summarize, to acquire authentication cookies the request needs to be sent to the following endpoint:

url: https://tenant.sharepoint.com/_forms/default.aspx?wa=wsignin1.0  
method: POST
data: security token

Once the request is validated the response will contain authentication cookies (FedAuth and rtFa) in the HTTP header as explained in the article that you mentioned.

SharePoint Online REST client for Python

As a proof of concept the SharePoint Online REST client for Python has been released which shows how to:

  • perform remote authentication in SharePoint Online
  • perform basic CRUD operations against SharePoint resources such as Web, List or List Item using REST API

Implementation details:

  • AuthenticationContext.py class contains the SharePoint Online remote authentication flow implementation, in particular the acquireAuthenticationCookie function demonstrates how to handle authentication cookies
  • ClientRequest.py class shows how to consume SharePoint Online REST API

Examples

The example shows how to read Web client object properties:

from client.AuthenticationContext import AuthenticationContext
from client.ClientRequest import ClientRequest

url = "https://contoso.sharepoint.com/"
username = "[email protected]"
password = "password"


ctxAuth = AuthenticationContext(url)
if ctxAuth.acquireTokenForUser(username, password):
  request = ClientRequest(url,ctxAuth)
  requestUrl = "/_api/web/"   #Web resource endpoint
  data = request.executeQuery(requestUrl=requestUrl)

  webTitle = data['d']['Title']
  print "Web title: {0}".format(webTitle)

else:
  print ctxAuth.getLastErrorMessage()

More examples could be found under examples folder of GitHub repository

Share:
14,035
wnnmaw
Author by

wnnmaw

Updated on June 04, 2022

Comments

  • wnnmaw
    wnnmaw almost 2 years

    I am attempting to write a script with SharePoint package to access files on my company's SharePoint. The tutorial states

    First, you need to create a SharePointSite object. We’ll assume you’re using basic auth; if you’re not, you’ll need to create an appropriate urllib2 Opener yourself.

    However, after several attempts, I've concluded that basic auth is not sufficient. While researching how to try to make it work, I came upon this article which gives a good overview of the general scheme of authentication. What I'm struggling with is implementing this in Python.

    I've managed to hijack the basic auth in the SharePoint module. To do this, I took the XML message in the linked article and used it to replace the XML generated by the SharePoint module. After making a few other changes, I now recieve a token as described in Step 2 of the linked article.

    Now, in Step 3, I need to send that token to SharePoint with a POST. The below is a sample of what it should look like:

    POST http://yourdomain.sharepoint.com/_forms/default.aspx?wa=wsignin1.0 HTTP/1.1
    Host: yourdomain.sharepoint.com
    User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
    Content-Length: [calculate]
    
    t=EwBgAk6hB....abbreviated
    

    I currently use the following code to generate my POST. With the guidance from a few other questions, I've omitted the content-length header since that should be automatically calculated. I was unsure of where to put the token, so I just shoved it in data.

    headers = {
        'Host': 'mydomain.sharepoint.com',
        'Connection': 'keep-alive',
        'User-Agent': 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)'
    }
    
    data = {'t':'{}'.format(token[2:])}
    data = urlencode(data) 
    
    postURL = "https://mydomain.sharepoint.com/_forms/default.aspx?wa=wsignin1.0"   
    req = Request(postURL, data, headers) 
    response = urlopen(req)
    

    However, this produces the following error message:

    urllib2.HTTPError: HTTP Error 302: The HTTP server returned a redirect error that would lead to an infinite loop.
    The last 30x error message was:
    Found
    

    How do I generate a POST which will correctly return the authentication cookies I need?

  • wnnmaw
    wnnmaw about 8 years
    This is brilliant, one question though, is there any way to employ this where I can hand the good authentication back to the SharePoint module?
  • Vadim Gremyachev
    Vadim Gremyachev about 8 years
    If I understood the question properly, you would like to pass auth context to SharePoint module, that's doable, but we we need to introduce a handler to pass with cookie to request. Note: the specified module consumes SharePoint Web Services API which Microsoft marked as deprecated
  • wnnmaw
    wnnmaw about 8 years
    Yes, that is correct. While client does give me access wonderfully, I have no idea how to use it to check out and edit files. While the SharePoint module has "limited support" at least I would have a starting point. If we could jury-rig SharePoint module to use your client for authentication, that would be ideal, even if it is deprecated. However, now we're getting out of the scope of this question :)
  • IsaacS
    IsaacS over 6 years
    Sample code here is outdated but its repo has an updated readme.