Sharepoint authentication with python - python

I'm trying to use python to download an excel file that is hosted in a sharepoint which is part of the Microsoft Azure platform. I tried to retrieve the file with HTTPforhumans's request by doing:
r = requests.get(url)
But my requests keep getting denied (r.status_code returns 200) because I need to login to a valid account before trying to access the file. I do have a valid account and password, and I can access to my account and to the excel file via the browser. But I have no idea how to deal wit the Azure authentication procedure. And apparently it is not as easy as just doing:
auth = HTTPBasicAuth('email#somewhere.com', 'pass1234')
r = requests.post(url=url, auth=auth)
It is my uderstanding that there's a flow to follow, but when I try to read the documentation, it just goes over my head (I'm an engineer and I do not have experience in this kind of environment).
Can someone guide me in the process of how to login and download the file?

Try O365 rest python client library.it supports SharePoint Online authentication and allows to download/upload a file as demonstrated below: Please find the code here:
ctx_auth = AuthenticationContext(url)
ctx_auth.acquire_token_for_user(username,password)
ctx = ClientContext(url, ctx_auth)
response = File.open_binary(context, "/Shared Documents/User Guide.docx")
with open("./User Guide.docx", "wb") as local_file:
local_file.write(response.content)
You can download the latest version using below command
pip install git+https://github.com/vgrem/Office365-REST-Python-Client.git
For further reference please visit link
hope it helps.

Related

Connecting to an API at azurewebsites.net to download a JSON file

I need to connect an API on azurewebsites using Python to download a JSON file automatically.
I can access the website and download a JSON file manually.
I tried to connect using:
url = 'https://myplatformconnectiot.azurewebsites.net/swagger/index.html'
r = requests.get(url, headers={"Authentication": " application/json"},cookies={},auth=('user#example.com', 'password'),)
r.json()
Do you know how to download a JSON file in azurewebsites using Python?
You need to use the kudu console url to a get particular file download from a web app.
By using the below python code you can download the file form the web app
import json
import requests
url = 'https://<webappname>.scm.azurewebsites.net/wwwroot/wwwroot/css/site.css'
r = requests.get(url,auth=('username','urlpassword'))
with open(r'C:\Users\name.json','wb') as f:
f.write(r.content)
username & password will be from publish profile credentials file of a web app. you can get the publish profile credentials from portal as shown in below image
Kudu is the engine behind a number of features in Azure App Service related to source control based deployment, and other deployment methods like Dropbox and OneDrive sync.
for more information about kudu you can refer the below document

Error AADSTS500011 accessing SharePoint Online site with Azure AD App-Only using Office365-REST-Python-Client

I am trying to connect to a SharePoint Online site with Azure AD App-Only. I am using Office365-REST-Python-Client v2.3.5 (https://github.com/vgrem/Office365-REST-Python-Client).
I have followed the instructions of the following link to grant access via Azure AD App-Only: https://learn.microsoft.com/en-us/sharepoint/dev/solution-guidance/security-apponly-azuread. API Permission Sites.FullControl.All has been granted to my application via "Application Permissions" in the Microsoft Azure Portal. I have also made sure that admin consent has been granted to the API Permissions.
I am able to successfully access my SharePoint Online root site https://{my_tenant_name}.sharepoint.com and upload files to the document library "Documents" without any problems. But if I try to access another SharePoint Online site, https://{my_tenant_name}.sharepoint.com/sites/test, other than my the root site, I receive the following error:
"AADSTS500011: The resource principal named https://{my_tenant_name}.sharepoint.com/sites/test was not found in the tenant named {tenant_guid}. This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant. You might have sent your authentication request to the wrong tenant."
I have double-checked the SharePoint Online site url, the tenant guid and API permissions including consent by admin but I am not sure what is causing the error.
Below is my code which can reproduce the problem:
from office365.sharepoint.client_context import ClientContext
# Access to the SharePoint Online root site works
# site_url = 'https://{my_tenant_name}.sharepoint.com'
# Other than SharePoint Online root site gives AADSTS500011 error
site_url = 'https://{my_tenant_name}.sharepoint.com/sites/test'
app_settings = {
'tenant': '{my_tenant_name}.onmicrosoft.com',
'client_id': '<$guid>',
'thumbprint': "<$base64CertHash>",
'certificate_path': 'selfsigned_certificate.pem',
}
ctx = ClientContext(site_url).with_client_certificate(
app_settings.get('tenant'),
app_settings.get('client_id'),
app_settings.get('thumbprint'),
app_settings.get('certificate_path')
)
current_web = ctx.web
ctx.load(current_web)
ctx.execute_query()
print("current_web.url: {}".format(current_web.url))
Try giving the application the following API permissions:
Files.ReadWrite.All
Sites.ReadWrite.All
With this access we are able to use the SharePoint features from the Microsoft Graph API. We use the following code to get a token:
import msal
# Get a token
auth = f'https://login.microsoftonline.com/{tenant_id}'
app = msal.ConfidentialClientApplication(
client_id, authority=auth, client_credential=client_secret)
result = app.acquire_token_for_client(scopes=['https://graph.microsoft.com/.default'])
token = result['access_token']
Retrieving a list then looks like this (ref):
import requests
# Define the headers of the request
headers = {'Authorization': "Bearer " + token}
# Make the GET request to the Graph API to get the list
resp = requests.get(
'https://graph.microsoft.com/v1.0/sites/{site_id}/lists/{list_title}',
headers=headers
).json()
print(resp)

Authentication OneDrive API Python

Using code sample from GitHub that is specifically for setting up authentication for Python access to OneDrive API (I'm beginning to think this source is outdated), I've failed to make it past the part where you paste code provided by Microsoft after executing program..
Python code:
import onedrivesdk
redirect_uri = 'https://login.microsoftonline.com/common/oauth2/nativeclient'
client_secret = '*this code omitted*'
client_id='*this code omitted*'
api_base_url='https://api.onedrive.com/v1.0/'
scopes=['onedrive.readwrite']
http_provider = onedrivesdk.HttpProvider()
auth_provider = onedrivesdk.AuthProvider(
http_provider=http_provider,
client_id=client_id,
scopes=scopes)
client = onedrivesdk.OneDriveClient(api_base_url, auth_provider, http_provider)
auth_url = client.auth_provider.get_auth_url(redirect_uri)
# Ask for the code
print('Paste this URL into your browser, approve the app\'s access.')
print('Copy everything in the address bar after "code=", and paste it below.')
print(auth_url)
code = raw_input('Paste code here: ')
client.auth_provider.authenticate(code, redirect_uri, client_secret)
After executing code and pasting url in browser, a popup shows up, where I verify that I want to give my app access to API.. I hit "Ok."
I am then presented with code in URL taskbar. I copy and paste code into program..
Then the error I get is:
raise Exception(str(message["error"]))
Exception: invalid_request
Link to GitHub source used: https://github.com/OneDrive/onedrive-sdk-python
Note: I had to omit scopes such as the first two in this list:
scopes=['wl.signin', 'wl.offline_access', 'onedrive.readwrite']
because they apparently don't exist (according to error code provided by Microsoft after pasting URL into taskbar)
Is there a better source for setting up authentication for a Python program to communicate with OneDrive API?
I am a relatively new Python user, your patience is appreciated.
I ran into the same issue and the solution was to include the redirect_uri in the app registration.
This can be done at https://portal.azure.com/ und Azure Active Directory > App registrations > "Your App" > Authentication. In my case, I needed to add http://localhost:8080/ to the redirect URIs.
I found the suggestion here:
https://github.com/OneDrive/onedrive-sdk-python/issues/98
Hope it helps someone save some time.

python linkedin oauth2 - where is http_api.py?

I'm trying to get this example to work from https://github.com/ozgur/python-linkedin. I'm using his example. When I run this code. I don't get the RETURN_URL and authorization_code talked about in the example. I'm not sure why, I think it is because I'm not setting up the HTTP API example correctly. I can't find http_api.py, and when I visit http://localhost:8080, I get a "this site can't be reached".
from linkedin import linkedin
API_KEY = 'wFNJekVpDCJtRPFX812pQsJee-gt0zO4X5XmG6wcfSOSlLocxodAXNMbl0_hw3Vl'
API_SECRET = 'daJDa6_8UcnGMw1yuq9TjoO_PMKukXMo8vEMo7Qv5J-G3SPgrAV0FqFCd0TNjQyG'
RETURN_URL = 'http://localhost:8000'
authentication = linkedin.LinkedInAuthentication(API_KEY, API_SECRET, RETURN_URL, linkedin.PERMISSIONS.enums.values())
# Optionally one can send custom "state" value that will be returned from OAuth server
# It can be used to track your user state or something else (it's up to you)
# Be aware that this value is sent to OAuth server AS IS - make sure to encode or hash it
#authorization.state = 'your_encoded_message'
print authentication.authorization_url # open this url on your browser
application = linkedin.LinkedInApplication(authentication)
http_api.py is one of the examples provided in the package. This is an HTTP server that will handle the response from LinkedIn's OAuth end point, so you'll need to boot it up for the example to work.
As stated in the guide, you'll need to execute that example file to get the server working. Note you'll also need to supply the following environment variables: LINKEDIN_API_KEY and LINKEDIN_API_SECRET.
You can run the example file by downloading the repo and calling LINKEDIN_API_KEY=yourkey LINKEDIN_API_SECRET=yoursecret python examples/http_api.py. Note you'll need Python 3.4 for it to work.

401 Unauthorized making REST Call to Azure API App using Bearer token

I created 2 applications in my Azure directory, 1 for my API Server and one for my API client. I am using the Python ADAL Library and can successfully obtain a token using the following code:
tenant_id = "abc123-abc123-abc123"
context = adal.AuthenticationContext('https://login.microsoftonline.com/' + tenant_id)
token = context.acquire_token_with_username_password(
'https://myapiserver.azurewebsites.net/',
'myuser',
'mypassword',
'my_apiclient_client_id'
)
I then try to send a request to my API app using the following method but keep getting 'unauthorized':
at = token['accessToken']
id_token = "Bearer {0}".format(at)
response = requests.get('https://myapiserver.azurewebsites.net/', headers={"Authorization": id_token})
I am able to successfully login using myuser/mypass from the loginurl. I have also given the client app access to the server app in Azure AD.
Although the question was posted a long time ago, I'll try to provide an answer. I stumbled across the question because we had the exact same problem here. We could successfully obtain a token with the adal library but then we were not able to access the resource I obtained the token for.
To make things worse, we sat up a simple console app in .Net, used the exact same parameters, and it was working. We could also copy the token obtained through the .Net app and use it in our Python request and it worked (this one is kind of obvious, but made us confident that the problem was not related to how I assemble the request).
The source of the problem was in the end in the oauth2_client of the adal python package. When I compared the actual HTTP requests sent by the .Net and the python app, a subtle difference was that the python app sent a POST request explicitly asking for api-version=1.0.
POST https://login.microsoftonline.com/common//oauth2/token?api-version=1.0
Once I changed the following line in oauth2_client.py in the adal library, I could access my resource.
Changed
return urlparse('{}?{}'.format(self._token_endpoint, urlencode(parameters)))
in the method _create_token_url, to
return urlparse(self._token_endpoint)
We are working on a pull request to patch the library in github.
For the current release of Azure Python SDK, it support authentication with a service principal. It does not support authentication using an ADAL library yet. Maybe it will in future releases.
See https://azure-sdk-for-python.readthedocs.io/en/latest/resourcemanagement.html#authentication for details.
See also Azure Active Directory Authentication Libraries for the platforms ADAL is available on.
#Derek,
Could you set your Issue URL on Azure Portal? If I set the wrong Issue URL, I could get the same error with you. It seems that your code is right.
Base on my experience, you need add your application into Azure AD and get a client ID.(I am sure you have done this.) And then you can get the tenant ID and input into Issue URL textbox on Azure portal.
NOTE:
On old portal(manage.windowsazure.com),in the bottom command bar, click View Endpoints, and then copy the Federation Metadata Document URL and download that document or navigate to it in a browser.
Within the root EntityDescriptor element, there should be an entityID attribute of the form https://sts.windows.net/ followed by a GUID specific to your tenant (called a "tenant ID"). Copy this value - it will serve as your Issuer URL. You will configure your application to use this later.
My demo is as following:
import adal
import requests
TenantURL='https://login.microsoftonline.com/*******'
context = adal.AuthenticationContext(TenantURL)
RESOURCE = 'http://wi****.azurewebsites.net'
ClientID='****'
ClientSect='7****'
token_response = context.acquire_token_with_client_credentials(
RESOURCE,
ClientID,
ClientSect
)
access_token = token_response.get('accessToken')
print(access_token)
id_token = "Bearer {0}".format(access_token)
response = requests.get(RESOURCE, headers={"Authorization": id_token})
print(response)
Please try to modified it. Any updates, please let me know.

Categories

Resources