55import requests .utils
66import office365 .logger
77from office365 .runtime .auth .base_token_provider import BaseTokenProvider
8- from office365 .runtime .auth .sts_info import STSInfo
8+ from office365 .runtime .auth .sts_profile import STSProfile
99from office365 .runtime .auth .user_realm_info import UserRealmInfo
1010
1111office365 .logger .ensure_debug_secrets ()
@@ -18,12 +18,10 @@ def __init__(self, authority_url, username, password):
1818 self .__username = username
1919 self .__password = password
2020 # Security Token Service info
21- self .sts = STSInfo (authority_url )
21+ self .__sts_profile = STSProfile (authority_url )
2222 # Last occurred error
2323 self .error = ''
24- self .FedAuth = None
25- self .rtFa = None
26- self ._auth_cookies = []
24+ self ._auth_cookies = {}
2725 self .__ns_prefixes = {
2826 'S' : '{http://www.w3.org/2003/05/soap-envelope}' ,
2927 's' : '{http://www.w3.org/2003/05/soap-envelope}' ,
@@ -53,15 +51,14 @@ def acquire_token(self, **kwargs):
5351 token = self .acquire_service_token_from_adfs (user_realm .STSAuthUrl , self .__username , self .__password )
5452 else :
5553 token = self .acquire_service_token (self .__username , self .__password )
56- self .acquire_authentication_cookie (token )
57- return True
54+ return self .acquire_authentication_cookie (token , user_realm .IsFederated )
5855 except requests .exceptions .RequestException as e :
5956 self .error = "Error: {}" .format (e )
6057 return False
6158
6259 def get_user_realm (self , login ):
6360 """Get User Realm"""
64- response = requests .post (self .sts .userRealmServiceUrl , data = "login={0}&xml=1" .format (login ),
61+ response = requests .post (self .__sts_profile .userRealmServiceUrl , data = "login={0}&xml=1" .format (login ),
6562 headers = {'Content-Type' : 'application/x-www-form-urlencoded' })
6663 xml = ElementTree .fromstring (response .content )
6764 node = xml .find ('NameSpaceType' )
@@ -76,9 +73,8 @@ def get_user_realm(self, login):
7673 def get_authentication_cookie (self ):
7774 """Generate Auth Cookie"""
7875 logger = self .logger (self .get_authentication_cookie .__name__ )
79-
80- logger .debug_secrets ("self.FedAuth: %s\n self.rtFa: %s" , self .FedAuth , self .rtFa )
81- return 'FedAuth=' + self .FedAuth + '; rtFa=' + self .rtFa
76+ logger .debug_secrets (self ._auth_cookies )
77+ return "; " .join (["=" .join ([key , str (val )]) for key , val in self ._auth_cookies .items ()])
8278
8379 def get_last_error (self ):
8480 return self .error
@@ -90,9 +86,9 @@ def acquire_service_token_from_adfs(self, adfs_url, username, password):
9086 'username' : username ,
9187 'password' : password ,
9288 'message_id' : str (uuid .uuid4 ()),
93- 'created' : self .sts .created ,
94- 'expires' : self .sts .expires ,
95- 'issuer' : self .sts .federationTokenIssuer
89+ 'created' : self .__sts_profile .created ,
90+ 'expires' : self .__sts_profile .expires ,
91+ 'issuer' : self .__sts_profile .federationTokenIssuer
9692 })
9793 response = requests .post (adfs_url , data = payload ,
9894 headers = {'Content-Type' : 'application/soap+xml; charset=utf-8' })
@@ -107,10 +103,11 @@ def acquire_service_token_from_adfs(self, adfs_url, username, password):
107103 logger .error (self .error )
108104 return None
109105 # 2. prepare & submit token request
110- self .sts .securityTokenServicePath = 'rst2.srf'
106+ self .__sts_profile .signInPage = '_vti_bin/idcrl.svc'
107+ self .__sts_profile .securityTokenServicePath = 'rst2.srf'
111108 template = self ._prepare_request_from_template ('RST2.xml' , {
112- 'auth_url' : self .sts .authorityUrl ,
113- 'serviceTokenUrl' : self .sts .securityTokenServiceUrl
109+ 'auth_url' : self .__sts_profile .authorityUrl ,
110+ 'serviceTokenUrl' : self .__sts_profile .securityTokenServiceUrl
114111 })
115112 template_xml = ElementTree .fromstring (template )
116113 security_node = template_xml .find (
@@ -119,7 +116,7 @@ def acquire_service_token_from_adfs(self, adfs_url, username, password):
119116 security_node .insert (1 , assertion_node )
120117 payload = ElementTree .tostring (template_xml ).decode ()
121118 # 3. get token
122- response = requests .post (self .sts .securityTokenServiceUrl , data = payload ,
119+ response = requests .post (self .__sts_profile .securityTokenServiceUrl , data = payload ,
123120 headers = {'Content-Type' : 'application/soap+xml' })
124121 token = self ._process_service_token_response (response )
125122 logger .debug_secrets ('security token: %s' , token )
@@ -133,16 +130,16 @@ def acquire_service_token(self, username, password, service_target=None, service
133130 """Retrieve service token"""
134131 logger = self .logger (self .acquire_service_token .__name__ )
135132 payload = self ._prepare_request_from_template ('SAML.xml' , {
136- 'auth_url' : self .sts .authorityUrl ,
133+ 'auth_url' : self .__sts_profile .authorityUrl ,
137134 'username' : username ,
138135 'password' : password ,
139136 'message_id' : str (uuid .uuid4 ()),
140- 'created' : self .sts .created ,
141- 'expires' : self .sts .expires ,
142- 'issuer' : self .sts .federationTokenIssuer
137+ 'created' : self .__sts_profile .created ,
138+ 'expires' : self .__sts_profile .expires ,
139+ 'issuer' : self .__sts_profile .federationTokenIssuer
143140 })
144141 logger .debug_secrets ('options: %s' , payload )
145- response = requests .post (self .sts .securityTokenServiceUrl , data = payload ,
142+ response = requests .post (self .__sts_profile .securityTokenServiceUrl , data = payload ,
146143 headers = {'Content-Type' : 'application/x-www-form-urlencoded' })
147144 token = self ._process_service_token_response (response )
148145 logger .debug_secrets ('security token: %s' , token )
@@ -161,8 +158,9 @@ def _process_service_token_response(self, response):
161158
162159 # check for errors
163160 if xml .find ('{0}Body/{0}Fault' .format (self .__ns_prefixes ['s' ])) is not None :
164- error = xml .find ('{0}Body/{0}Fault/{0}Detail/{1}error/{1}internalerror/{1}text' .format (self .__ns_prefixes ['s' ],
165- self .__ns_prefixes ['psf' ]))
161+ error = xml .find (
162+ '{0}Body/{0}Fault/{0}Detail/{1}error/{1}internalerror/{1}text' .format (self .__ns_prefixes ['s' ],
163+ self .__ns_prefixes ['psf' ]))
166164 if error is None :
167165 self .error = 'An error occurred while retrieving token from XML response.'
168166 else :
@@ -175,30 +173,43 @@ def _process_service_token_response(self, response):
175173 '{0}Body/{1}RequestSecurityTokenResponse/{1}RequestedSecurityToken/{2}BinarySecurityToken' .format (
176174 self .__ns_prefixes ['s' ], self .__ns_prefixes ['wst' ], self .__ns_prefixes ['wsse' ]))
177175 if token is None :
178- self .error = 'Cannot get binary security token for from {0}' .format (self .sts .securityTokenServiceUrl )
176+ self .error = 'Cannot get binary security token for from {0}' .format (
177+ self .__sts_profile .securityTokenServiceUrl )
179178 logger .error (self .error )
180179 return None
181180 logger .debug_secrets ("token: %s" , token )
182181 return token .text
183182
184- def acquire_authentication_cookie (self , security_token ):
185- """Retrieve SPO auth cookie"""
183+ def acquire_authentication_cookie (self , security_token , federated = False ):
184+ """Retrieve auth cookie from STS """
186185 logger = self .logger (self .acquire_authentication_cookie .__name__ )
187186 session = requests .session ()
188- logger .debug_secrets ("session: %s\n session.post(%s, data=%s)" , session , self .sts .signInPageUrl ,
187+ logger .debug_secrets ("session: %s\n session.post(%s, data=%s)" , session , self .__sts_profile .signInPageUrl ,
189188 security_token )
190- session .post (self .sts .signInPageUrl , data = security_token ,
191- headers = {'Content-Type' : 'application/x-www-form-urlencoded' })
189+ if not federated :
190+ self ._auth_cookies ['FedAuth' ] = None
191+ self ._auth_cookies ['rtFa' ] = None
192+ session .post (self .__sts_profile .signInPageUrl , data = security_token ,
193+ headers = {'Content-Type' : 'application/x-www-form-urlencoded' })
194+ else :
195+ self ._auth_cookies ['SPOIDCRL' ] = None
196+ session .head (self .__sts_profile .signInPageUrl ,
197+ headers = {
198+ 'User-Agent' : 'Office365 Python Client' ,
199+ 'X-IDCRL_ACCEPTED' : 't' ,
200+ 'Authorization' : 'BPOSIDCRL {0}' .format (security_token ),
201+ 'Content-Type' : 'application/x-www-form-urlencoded'
202+ })
192203 logger .debug_secrets ("session.cookies: %s" , session .cookies )
193204 cookies = requests .utils .dict_from_cookiejar (session .cookies )
194205 logger .debug_secrets ("cookies: %s" , cookies )
195- if 'FedAuth' in cookies and 'rtFa' in cookies :
196- self .FedAuth = cookies [ 'FedAuth' ]
197- self .rtFa = cookies [ 'rtFa' ]
198- return True
199- self . error = "An error occurred while retrieving auth cookies"
200- logger . error ( self .error )
201- return False
206+ if not cookies :
207+ self .error = "An error occurred while retrieving auth cookies from {0}" . format ( self . __sts_profile . signInPageUrl )
208+ logger . error ( self .error )
209+ return False
210+ for name in self . _auth_cookies . keys ():
211+ self ._auth_cookies [ name ] = cookies [ name ]
212+ return True
202213
203214 @staticmethod
204215 def _prepare_request_from_template (template_name , params ):
0 commit comments