Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save tobiasviehweger/7b0901e0459ac286b113f0d97076f7af to your computer and use it in GitHub Desktop.
Save tobiasviehweger/7b0901e0459ac286b113f0d97076f7af to your computer and use it in GitHub Desktop.
Quick and dirty example of how to authenticate to Office 365 SharePoint Online using urllib2, jinja2, cookielib. Basically you POST your user/pass to Microsoft's token service, then hand that token to SharePoint's login proper, which gives you a cookie to access SharePoint content.
import urllib2
import cookielib
import urlparse
import jinja2
from urllib2 import HTTPCookieProcessor
from lxml import etree
# Setup Jinja for SAML
JINJA_TEMPLATE_PATH = "/Users/Brian/IdeaProjects/yggdrasil/templates"
JINJA_ENVIRONMENT = jinja2.Environment(
loader=jinja2.FileSystemLoader(JINJA_TEMPLATE_PATH),
extensions=['jinja2.ext.autoescape'],
autoescape=True)
saml_template = JINJA_ENVIRONMENT.get_template('saml.xml')
# lxml needs namespaces
namespaces = {'S': "http://www.w3.org/2003/05/soap-envelope",
'wst': "http://schemas.xmlsoap.org/ws/2005/02/trust",
'wsse': "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd",
'wsu': "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd",
'saml': "urn:oasis:names:tc:SAML:1.0:assertion",
'wsp': "http://schemas.xmlsoap.org/ws/2004/09/policy",
'psf': "http://schemas.microsoft.com/Passport/SoapServices/SOAPFault"}
# This is the external microsoft service that will handout a token when given credentials
mso_auth_uri = "https://login.microsoftonline.com/extSTS.srf"
# Authentication front-end for SharePoint Online (hand it a token, gives us a cookie)
spo_auth_uri = "/_forms/default.aspx?wa=wsignin1.0"
# Change this stuff
username = "user@mydomain.onmicrosoft.com"
password = "p@ssword1"
sp_site = "https://mydomain.sharepoint.com"
sp_login_uri = urlparse.urljoin(sp_site, spo_auth_uri)
# file we want
sp_url = "https://mydomain.sharepoint.com/_vti_bin/ListData.svc/"
# xpath for binarytoken (not valid for pre-Office 365 SPO, probably doesn't apply to you)
tokenpath = "/S:Envelope/S:Body/wst:RequestSecurityTokenResponse/wst:RequestedSecurityToken/wsse:BinarySecurityToken"
# populate SAML + need cookie jar to magically handout cookies.
login_vars = {'username': username, 'password': password, 'url': sp_url}
saml = saml_template.render(login_vars)
jar = cookielib.CookieJar()
opener = urllib2.build_opener(HTTPCookieProcessor(jar))
# MSO/SPO prefers a browser UA
opener.addheaders = [
('User-Agent', 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2.11) Gecko/20101012 Firefox/3.6.11')]
# 1. Get the token from MSO
f = opener.open(mso_auth_uri, saml)
tree = etree.parse(f)
# 2. Receive SAML response, store token
binarytoken = tree.xpath(tokenpath, namespaces=namespaces)[0].text
# 3. Post token to sharepoint online to get cookie
opener.open(sp_login_uri, data=binarytoken)
# 4/5 CookieJar will handle the cookies, request what we actually want.
resp = opener.open(sp_url)
# Do something interesting...
print resp.read()
<?xml version="1.0" encoding="UTF-8"?>
<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">https://login.microsoftonline.com/extSTS.srf</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">
<o:UsernameToken>
<o:Username>{{ username }}</o:Username>
<o:Password>{{ password }}</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">
<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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment