I have a OneDrive for Business user account within a large organization. I'd like to have a daemon service running (Python) that automatically uploads files to this user's OneDrive.
This service will be running in a headless VM, so browser-based authentication (especially if it needs to be done more than once) is very difficult.
What are my options for authenticating this app to allow it to write to the user's OneDrive? I've registered an app and created a client secret for it. I was experimenting with the authorization flow described here, but that SDK is deprecated and no longer supported, so I'd prefer to use Graph if possible.
What are my options for authentication with Python in this scenario, and is any sample code / example available?
Both delegated and application permissions are supported on MS Graph API: https://learn.microsoft.com/en-us/graph/api/drive-list?view=graph-rest-1.0&tabs=http. Application permissions might not be acceptable for your use case since they would allow access to all users' OneDrives?
Application permissions would definitely be the easiest choice.
But you can also implement this scenario using delegated permissions
You would need the user to initialize the process by authenticating interactively once.
When they do that, store the refresh token in a secret store accessible by the server application.
Then it can use the refresh token to get a new refresh token + access token when needed.
This approach has some more complexity but does allow you to only give access to this one user's OneDrive for the app.
Also, keep in mind that refresh tokens can expire.
The user would need to re-authenticate if that happens.
If this process is critical, application permissions can be a really good idea despite the downsides.
Related
I'm trying to make an app and I can't figure out how to sign in to a user with the python library firebase_admin. I don't have any code as of this moment. Let me know if you can help me out.
The Firebase Admin SDK is designed to be used in a trusted environment, such as your development machine, a server you control, or Cloud Functions/Cloud Run. It gets its authorization from its context or from a credentials file that you provide to it, and which gives it full, administrative access to the project. Therefor it doesn't need, and doesn't have a way, to sign in as a specific user.
If your use-case requires that you sign a user in to Firebase from your Python code, you can consider calling the REST API to authenticate. But the use-case for this would typically be to then pass the ID token you receive back to a user (similar to the use-case in creating custom tokens).
My setup is as follows:
I make API calls from python scripts activated in excel, using the wonderful xlwings.
This enables complex data extraction and transformation workflows to be coded in nice python instead of annoying VBA. It also makes these workflows available to non-coding users at the click of an embedded button.
My problem:
My API calls used hardcoded API keys in the past. This is a big security no-no. Now my API calls need to go through OIDC (OAuth2) authentication in Azure AD.
My questions:
Is it possible to trigger OIDC authentication (in Azure AD) from a local Python script?
Where could I securely store my client secret in such a setup?
Yes you can do this. You don't say which APIs you are calling but any of them act the same.
There are two types of authentication: interactive and non-interactive. You'll need to describe the one you want, but since you're concerned about hard-coded keys, let's assume that you want interactive.
This means that when a user wants to access the data, the user is prompted for credentials in a browser. An access token is returned to the application which is then used to call the APIs. No hardcoded keys are used and the token expires after a period of time.
You can get started by referring to this documenation: https://learn.microsoft.com/en-us/azure/developer/python/azure-sdk-authenticate
Is there any way to use Python to access the Google Adsense API from a server without any user interaction?
This is typically done by setting up a "service account", but Google's docs say that "AdSense doesn't support Service Accounts".
They say to use the web or installed application flows, but these require the user to manually confirm access for every access. My application needs to run on a headless server, without user interaction, so it can pull data every hour, so this won't work. This similar question suggests going through the user consent screen once and then caching the token on the server, but this isn't feasible in my case since my process needs to be 100% automated, and the token will eventually expire and require user interaction.
Unfortunately, Google's docs are quiet unhelpful, and even worse their Python coding examples haven't been updated in 7 years, and don't even seem to have worked back then, as many of them don't even run Python 2.7, much less 3.
It's true that the AdSense Management API doesn't support service accounts. While there is setup required at first with the Web Flow, the same is true for service accounts which also have to be granted permissions on the account being accessed.
Regarding the tokens expiring, the Web Flow will yield a refresh token, which you can use to generate new access tokens (known as offline access, which doesn't require user involvement after the initial setup).
I want to have access to a specific work user's OneDrive. I could register an application in Azure AD and assign one of two types of permission(delegated or application).
Based on the Microsoft Documentation if I register an app with the application-level access it could have access to all users' drive and based on this question in Stackoverflow there is no way to limit this access to a specific drive. So I ignored this approach.
On the other hand, based on the Microsoft Documentation if I want to assign delegate permissions to the defined app I have to manually approve the access list on the consent page. This is not desired for me as I'm looking for a code-base solution which runs behind the scene regular bases.
Is there any solution that I could have access to a specific OneDrive by python code?
If you want to connect with only 1 user's Onedrive you can use ROPC flow which can work in your scenario. But this is not recommended by microsoft because of security concerns. And yes, if you have MFA enabled, you cannot use it.
One of the good recommendations can be to use Graph API for OneDrive.
For example, one of the use case can be to Get current user's OneDrive:
The signed in user's drive (when using delegated authentication) can
be accessed from the me singleton.
If a user's OneDrive is not provisioned but the user has a license to
use OneDrive, this request will automatically provision the user's
drive, when using delegated authentication.
Http Request:
GET /me/drive
Resources that will help you to call Graph API from Python:
https://github.com/microsoftgraph/python-security-rest-sample
Edit:
Further, I have found a way in which you can disable user consent.
To configure user consent settings through the Azure portal:
Sign in to the Azure portal as a Global Administrator.
Select Azure Active Directory > Enterprise applications > Consent and permissions > User consent settings.
Under User consent for applications, select Do not allow User Consent.
Select Save to save your settings.
If you want consent permissions other than this, you can design your own Consent.
I want to write a python script that can connect to Google Drive API without having to manually authenticate on every device the script is run on.
I am writing some python code for a research study that is going to be run at various study locations. For data privacy reasons, we cannot store data locally and need to write it to the cloud (ideally Google Drive). A member of our team will not present at all locations the software is being run, and thus any sort of initial manual authentication (entering username and password at the different sites for OAuth) is really off of the table for us.
I've looked into the Google Drive API (Python), and am wondering if there is a way for a device running my script to get a Refresh token (and subsequent Access tokens) to modify a Google Sheet without needling to manually authenticate on each device.
Is there any way to make this possible with the Google Drive API (by having some sort of 'secret' that the code could store)? If not, are there any other cloud services that may be able to accommodate this?
Additionally, the python script is being run as part of an executable (produced from Vizard, probably irrelevant but mentioning it just in case)
Yes it can be done - see How do I authorise an app (web or installed) without user intervention?
However, it's probably a bad idea for two reasons. if you distribute code with embedded secrets (technically the secret is a Refresh Token), they tend not to stay secret for long. Secondly, there is the chance that the Refresh Token will expire and your users will be dead in the water.
I would suggest that you consider:-
A Service Account
Writing an OAuth proxy, which you can host for free on Google AppEngine, which puts all of the secret stuff on a server and from which your app can fetch Access Tokens as they are needed.