OAuth2 Token on Microsoft Graph API - python

I'm looking for the most simple way to gain a JWT token to use when calling Graph API endpoints. There is endless documentation about OAuth2 and so many ways to do that, but I got lost in the process.
My scenario is a backend program listening to an Outlook mailbox.
I read about registering my service in Azure AD etc., but I'm looking for something quicker that bypasses everything. I know such solution exists because in the Graph Explorer it is done fairly easily. I only need the JWT token to make the calls work, nothing more.
I tried calling /common/oauth2/v2.0/token, but it needs a client_secret which I don't have because I haven't registered my service in Azure. I've tried endlessly to mimic the process that is done in Graph Explorer, but with no luck.

I’m sorry to announce that, but Graph Explorer is an Azure AD registered app by default and you will have no choice but to create an app, this is how Graph API works, and for that, you can follow this link for a non authenticated use https://learn.microsoft.com/en-us/graph/auth-v2-service or this link for calling Graph on behalf of a user https://learn.microsoft.com/en-us/graph/auth-v2-user

Related

Automate OneDrive Authentication with AAD MFA with python

I'm finding a way to automate the authentication from AAD with python.
In the past i used username and password for login to OneDrive and it worked properly. Here is the code:
pca = msal.PublicClientApplication(CLIENT_ID, authority=AUTHORITY_URL)
token = pca.acquire_token_by_username_password(USERNAME, PASSWORD, SCOPES)
Now, that i have two factor authentication i cannot use the same code to access OneDrive account.
I've searched the internet but all the solutions that i found requires to open the browser, and i can't do this because python script is a chronjob and runs in the late night. I need a solution that works in "background" without any action required.
Possibly it's better if there is a solution with MSAL library due to some permissions that i should request if i would change the library.
Thanks for the help!
You might consider using the Client-Credentials Grant flow or OAuth2. You would have to modify your cronjob to move away from fetching a token on behalf of the user and update it to acquire a token as the application using the application's identity (the app registration done in AAD). Upgrading to client-credentials flow, which is actually designed for scenarios similar to yours, will help you in situations where you cannot afford user interaction and you want the service to work in the backend.
For more information on Client-Credentials flow, check here.
Also, you can refer to the following python app that implements client-credentials flow:
Call Microsoft Graph API using App Client Secret
Call Microsoft Graph API using App Client Certificate:

Is it possible to use the Spotify Web API to write a desktop application without a callback URI?

I would like to write a simple desktop application for personal use that uses the Spotify Web API to build playlists.
As far as I can tell, however, there's no way to use the API without providing a callback URI, which I don't have, seeing as I don't have a domain or server of any kind (other than my personal computer).
Is there a way to use the API without a URI?
If not, what is the best way to set up a callback URI? I don't have much of any experience working with web applications or client / server stuff, and the APIs I've used in the past haven't required any kind of callback.
Some background first, this answer became a bit longer than what I anticipated.
You need an access token. There are three ways to retrieve an access token; Authentication Code flow, Client Credentials flow, and Implicit Grant flow. These are all part of the oAuth 2.0 specification, each with its own purpose.
Since you're going to modify a user's account, you need that user's permission. Now, if you didn't do any actions that required user permissions, you could've used the Client Credentials flow. That's probably the easiest flow to learn since it just requires a request from your server to Spotify's server, and the response contains an access token. No callback/redirect URI is necessary.
As I'm sure you've read, the Authentication Code flow and Implicit Grant flow both require a callback URI. This is because a flow that includes a user, and the callback URI is where Spotify redirects the user after they have entered their password on Spotify's site.
The Authentication Code flow and Implicit Grant flow has benefits and drawbacks. Access tokens retrieved through the Authentication Code flow can be refreshed, but both return tokens that are valid for one hour. This means that a user that's authenticating using the Implicit Grant flow must reauthenticate after an hour. However, the Authentication Code flow does require some backend work, since it needs to make a request to exchange a code given from Spotify's server for an access token. The Implicit Grant flow is more straight forward - you get the access token and off you go.
The callback URI can be a localhost address, so if your desktop application would spin up a web server locally you could handle the callback on the same machine that the application is running on. (It's probably a good idea to not run the web server on port 80 since that might be used by something else.)
There's skeleton code for each of this authentication flows available on Github, see web-api-auth-examples. Read more about the flows in our Authorization Guide. If you choose to run a web server on the user's machine, I recommend that you use the Implicit Grant flow since that doesn't include any server-to-server requests, so you won't have to expose your client_secret exposed in the code. (As opposed to the Authorization Code flow.)
Also, since you're coding in Python, I recommend that you have a look at spotipy, a wrapper around the Web API packed with convenient methods that'll save you some time. If you do go ahead with the Implicit Grant flow, you should have a look at spotify-web-api-js, which has a similar purpose. Note that these wrappers are not at all required to work with the Web API but they'll make your life easier.

Where to store web authentication session in PySide?

I'm building a little application in Python. I use PySide for the GUI and Django to read data from my web application.
Everything works well, but I have a login access, like dropbox application.
I want to store this informations on the current machine (like a session, I don't want to login every time I open the application).
Now my question is, what is the safest way to do this? Environment variables?
Usually when you have an API that you're exposing in your app to the outer world (even your own desktop/mobile app), you'll design this API to be stateless, as part of the REST architecture. So your app should always include an HTTP header or any other method of carrying an authentication token that will let your API identify the user.
You only log in once, and when the log-in procedure is successful you should get an authentication token from your API, and then you will store this token somewhere safe.
You can also look into implementing OAuth2 for the authentication.

Google Cloud endpoints and service accounts returning :Oauth framework user didn't match oauth token user

Im trying to access a google cloud endpoint from a cmdline using service account similar to
https://code.google.com/p/google-api-python-client/source/browse/samples/service_account/tasks.py
As instructed from the example, I created a clientid + pk12 cert and using them to create the credential with the SignedJwtAsertionCredential call from the oauth2client.client module.
Works as expected when I call my cloud endpoint running on my local devserver however when I call the deployed gae cloud endpoint I get
Oauth framework user didn't match oauth token user.
Seems to be failing on the oauth.get_client_id(scope) call from user_id_token._set_bearer_user_vars().
When I added a traceback on the exception, it looks to be coming from _maybe_raise_exception
E 2014-01-02 10:30:53.926 raise NotAllowedError(error_detail)
E 2014-01-02 10:30:53.926 NotAllowedError
Is there a way to resolve this error without changing the app's authentication type? Seems to be not allowing the request due to the domain restriction?
My goal is to call the cloud-endpoint without having a user involved, not sure if i'm the right path using the SignedJwtAsertionCredential call or if possible?
Additional info.
The authentication type of the endpoint is set to "Google App Domain"
The user_required is True on the endpoint method
The access token generated from the SignedJwtAssertCredential is as expected when i use
https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=ya29.
The endpoint works as expected from the api explorer and when there is the auth flow involved.
Using the endpoints_proto_datastore library.
From extensive research I have come to the conclusion that implementing OAuth is not a viable authentication method for apps because of the simple fact that it is horrible to implement. After spending countless hours debugging and asking questions on Stackoverflow about a simple Twitter oAuth implementation, all while receiving countless wrong answers(which safely lets me deduce that a large percentage of developers don't know how to use OAuth) I decided to never again use OAUTH.
So I leave you with the words of the great French Emperor Napoleon Bonaparte
"Una retirada a tiempo es una victoria" -Napoleon Bonaparte
which basically means get out while your ahead and dont waste your time with OAUTH!
Additional information
while experiencing my frustrations with OAUTH I ended up doing some research on who actually came up with this headache inducing concept, and it turns out that the creator has quit this project and has actually publicly denounced OAUTH in his blog:
http://hueniverse.com/2012/07/oauth-2-0-and-the-road-to-hell/ interestingly titled the road the hell. So if the creator is not using OAUTH then you definitely shouldn't either. I have started a petition on https://petitions.whitehouse.gov/ to make the use of OAUTH illegal, so if you like you can join the fight and give us a vote, it is currently gaining traction and we appreciate any support, so go ahead and give it a vote.
The issue was due to the "Google Apps" Authentication Type selected for the application. This setting requires all accounts using the users api to be example.com accounts and the service account is obviously not one.
Once we changed the Auth Type to Google accounts, there was no issue with using service account and validating the client_id.

How can I call an endpoint in my appengine instance without doing oAuth? (Mirror API)

I am trying to create some Glassware with the Mirror API. I am new to using AppEngine and Jinja2. I have python experience but never with a web framework before. So basically I am very new at this.
I have modified the Python quickstart for the mirror API to include many of my endpoints and designs. Basically I want to be able to be able to POST data from a constrained device to Glass. I have an endpoint all setup which works to accept and parse out the data and send the timeline item.
My problem is that the device itself is acting all on it's own and cannot provide input, therefore when I call my app from it e.g. https://foo.appspot.com?operation=deviceData the app presents the auth page and then nothing happens. I can see in the logs that the auth page is being sent, but the device has no idea what to do with this.
Basically, I need a way where I can hardcode credentials and get around having to do oauth everytime. What is the recommended way to do this? Another app which doesn't require auth which passes the data along? This would be fine as I only need to set this up with one user right now, it is for an internal demo only.
Is it possible to set my credentials in a header and auth automatically without handling any return, more like how basic auth works?
There are also the "Simple API access" keys. Would these work in this situation, I tried creating browser and server keys and tried them on the device and in the browser by doinghttps://foo.appspot.com?operation=deviceData&key=KEY_HERE but in both cases I was still prompted to login. Is this what simple access keys are for? Do they not work with the mirror API?
Basically my question is, what's the easiest way to allow access to my apps endpoints without having to oAuth or having a hard coded user which auto-auths?
Here is the project that I started with: https://github.com/googleglass/mirror-quickstart-python

Categories