vgrem / Office365-REST-Python-Client

Microsoft 365 & Microsoft Graph Library for Python
MIT License
1.34k stars 336 forks source link

Cannot get binary security token for from https://login.microsoftonline.com/extSTS.srf #678

Open ghost opened 1 year ago

ghost commented 1 year ago
from office365.runtime.auth.authentication_context import AuthenticationContext
from office365.sharepoint.client_context import ClientContext
from office365.sharepoint.files.file import File

site_url = 'https://xxx.sharepoint.com/sites/xxx'
username = 'xxx@xxx.com'
password = 'xxx'

ctx_auth = AuthenticationContext(site_url)
ctx_auth.acquire_token_for_user(username, password)
ctx = ClientContext(site_url, ctx_auth)

file_url = '/sites/xxx/Shared Documents/General/Working/xxx.xlsx'
file = File.from_url(file_url, ctx)
content = file.read()

print(content)

and this is the error I get

Cannot get binary security token for from https://login.microsoftonline.com/extSTS.srf
Traceback (most recent call last):
  File "/Users/xxx/airflow-local/test/read_sp.py", line 10, in <module>
    ctx_auth.acquire_token_for_user(username, password)
  File "/Users/xxx/opt/anaconda3/envs/xxx/lib/python3.11/site-packages/office365/runtime/auth/authentication_context.py", line 82, in acquire_token_for_user
    return self._provider.ensure_authentication_cookie()
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/xxx/opt/anaconda3/envs/xxx/lib/python3.11/site-packages/office365/runtime/auth/providers/saml_token_provider.py", line 84, in ensure_authentication_cookie
    self._cached_auth_cookies = self.get_authentication_cookie()
                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/xxx/opt/anaconda3/envs/xxx/lib/python3.11/site-packages/office365/runtime/auth/providers/saml_token_provider.py", line 99, in get_authentication_cookie
    token = self._acquire_service_token()
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/xxx/opt/anaconda3/envs/xxx/lib/python3.11/site-packages/office365/runtime/auth/providers/saml_token_provider.py", line 176, in _acquire_service_token
    token = self._process_service_token_response(response)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/xxx/opt/anaconda3/envs/xxx/lib/python3.11/site-packages/office365/runtime/auth/providers/saml_token_provider.py", line 211, in _process_service_token_response
    raise ValueError(self.error)
ValueError: Cannot get binary security token for from https://login.microsoftonline.com/extSTS.srf

My account has no 2FA. I have no idea what causes this error, perhaps I need client_credentials too? And if I need client_credentials (with client_id and client_secret), which permission do I need to grant in api permission in Azure app, Files.Read.All and Sites.Read.All ? (This is an organization sharepoint.)

Edit: I ended up using ClientCredential but face this error instead 403 Client Error: Forbidden for url: https://xxx.sharepoint.com/sites/xxx/_api/Web/getFileByServerRelativeUrl('%2Fsites%2Fxxx%2FShared%2520Documents%2FGeneral%2FWorking%2Fwork_place.xlsx

cmosguy commented 1 year ago

@homieHolmes I am getting same error for the user credentials, is there some other secret to making things work that you figured out?

ghost commented 1 year ago

@cmosguy Beats me.

I ended up using ClientCredential because my business account has 2FA and I also cannot get app password because of permission issue. I suggest that you try what @vgrem mentioned here, Option 2 worked for me.

ClearSafety commented 1 week ago

The problem is with authentication. In my case, I couldn't use my credentials (user and password) because of the way my company setup the access to the Sharepoint.

The solution can be found in the section "Setting up an app-only principal with tenant permissions" of https://learn.microsoft.com/en-us/sharepoint/dev/solution-guidance/security-apponly-azureacs

Once you have access to client_id and client_secret, use them to create the authentication. Please, see the example below:

from office365.sharepoint.client_context import ClientContext from office365.runtime.auth.authentication_context import AuthenticationContext

client_id="{client id}" client_secret="{client secret}" url = "https://{tenant}.sharepoint.com/sites/{site}"

ctx_auth = AuthenticationContext(url) if ctx_auth.acquire_token_for_app(client_id, client_secret): ctx = ClientContext(url, ctx_auth) web = ctx.web ctx.load(web) ctx.execute_query() print("Web title: {0}".format(web.properties['Title']))

else: print(ctx_auth.get_last_error())