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 appropriateurllib2
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?
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.
As a proof of concept the SharePoint Online REST client for Python has been released which shows how to:
Implementation details:
AuthenticationContext.py
class contains the SharePoint
Online remote authentication flow implementation, in particular the
acquireAuthenticationCookie
function demonstrates how to handle
authentication cookiesClientRequest.py
class shows how to consume SharePoint Online REST APIExamples
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