Office365 Authentication: getting user email from access token - python

I am using python and django for my web application, and I am trying to use Microsoft Graph API for user sign in authentication to my app using their office365 credentials. I've read up on examples on the web and have been able to successfully get an authorization code and an access token. However I am not able to get a valid response from my GET API call, and get_me function. I keep getting a 500 error. I am using in my scopes openid, profile, and email. Any suggestions on what I am doing wrong

pythoncontacts ties Django and Office 365 together and Microsoft provides an example of connecting to the Graph API via Python.

The scopes you list won't be enough to actually make any API calls. Those scopes will get you an ID token and refresh token in the response, but that's it. To call API calls, you need to add the required scope (depending on what API calls you want to make).
If you're trying to call the Graph endpoint (https://graph.microsoft.com/) then, for example, if you want to just read the user's email, you can add Mail.Read to the scope array.
If you find the API call you want to make at https://graph.microsoft.io/en-us/docs, it should list what scope is required.

Related

Microsoft MSAL React SPA, and RESTful Django API

I don't know why I can't find confirmation in the docs, maybe I am not navigating them correctly, although MSAL seems to have options to fit it into any application. This is my first time integrating a SAML sso procedure into any of my web-apps. I am just looking for some clarity on the correct, and secure way to verify the person attempting to login, is actually logged in with the IDP.
I am confused at the part after confirmation of login is given to my redirect API, I currently have it all happening on the front-end, then submitting the response to my back-end. Which is a RESTful API built with Django, and postgres database. At this point, I am thinking I need to verify my accessToken for authenticity, but I am unsure if I should be creating another PublicClient instance in python, and then sending the same commands to the IDP.
To guess at this point, I'm thinking this is wrong, as I need to verify the token, rather than get another Access and Refresh token. I'm thinking I just need to verify there is a session open with the IDP, and that the Access Token matches. Can anyone shed some light on this, possibly provide even just some direction.
The client Python Django Web App uses the Microsoft Authentication Library (MSAL) to sign-in and obtain an Access Token from Azure AD.
The access token is used as a bearer token to authorize the user to call the Python Flask Web API protected by Azure AD.
The Python Flask Web API then receives a token for Azure Resource Management API using the On-Behalf-Of flow.
To learn more about handing access token validation at the API layer, look into this sample walkthrough: https://github.com/Azure-Samples/ms-identity-python-on-behalf-of#about-the-code
https://learn.microsoft.com/en-us/azure/active-directory/develop/access-tokens#validating-tokens

How to get a user's OAuth2/access token using Django allauth package

I am using django-allauth in my Django application, and my registration process is handled by Twitch, using allauth's Twitch provider. As of now, users can register on the website using Twitch, log out, and later log back in using Twitch with no problem. However, for making requests to some of Twitch API endpoints, I need the user's Twitch access token to be able to make requests on their behalf (such as following a channel, etc.).
On a very old github issues page I came upon a question regarding how to access the user's access token and the answer was to query the SocialToken model and find the logged-in user and the desired provider. But in my case my SocialToken model is empty and there are no tokens to be seen there, and I have no clue how to proceed to populate the model and add every new user's access token there, so that I can make requests on their behalf, given I have the correct scope.
Is there a way to add every new user's access token in SocialToken model? And is there a way to update the access token using the refresh token?
P.S. I'm thinking about having a celery task that makes a request to Twitch API every time a new user registers, and later refreshes the access token when it expires. But that seems like a hack, and not really a viable solution, plus, I need a user to be redirected to a certain callback URI as per Twitch API docs Maybe I'm just missing something.

How to validate AWS Cognito session code returned from Cognito CustomUI login page

I configured Cognito to use the custom website that AWS Cognito provides for signup/signin as specified here:
https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-app-ui-customization.html
I am perfectly able to signup and login within the AWS Cognito page:
https://<your_domain>/login?response_type=code&client_id=<your_app_client_id>&redirect_uri=<your_callback_url>
The problem is that, after a successful login, Cognito redirect to the redirect page that I set, and the redirect includes a "code" value as a GET parameter.
I can not find documentation of how to use that "code" parameter, but it surely needs to be validated by my Python backend in order to check if that code is a valid session for a given user.
Can you provide a sample Python code (using or not a library, maybe Warrant) and JavaScript code that can validate that "code" parameter? and also to get the email/name of the user of that "code" parameter?
Thanks!!
Since you are using Authorization Code Grant flow, it requires the following to be done in order to get a short lived id_token, long lived refresh_token and an access_token.
Note: This is the most difficult flow to implement. If you need a simplified authentication flow, use the implicit grant flow, which will return the id_token once the user logins with the login page.
For Authorization Code flow, it requires the following
Receive Authorization Code from the Login Redirect URL. The code is not for recurrent use and only needs to be used to get the access tokens.
This code can be exchanged for access tokens using a token endpoint provided by AWS Cognito. You need to send a HTTP POST request in the following format (Without PKCE).
GET https://mydomain.auth.us-east-1.amazoncognito.com/oauth2/authorize?
response_type=code&
client_id=ad398u21ijw3s9w3939&
redirect_uri=https://YOUR_APP/redirect_uri&
state=STATE&
scope=openid+profile+aws.cognito.signin.user.admin
For more details read the Token Endpoint documentation.
After receiving the tokens, store the refresh_token in a safe place to get new id_tokens and use the id_token to access the APIs.
The code that is returned is in the format of a jwt token. It's not clear to me exactly what the format of this token is
I don't have any sample python code (yet, this is a current interest/project) but there is Javascript code here https://github.com/aws/chalice/issues/563

How to get access token using oauth2 for Github api using python

I am building an app to access Github api in python using django. I am new to this building this kind of app for the first time.
I specified an link to get the access of a user's account like this
Now I can access the user's account. Now the problem is, I want to use oauth2 so that it doesn't ask for username and password for each request.
my question is how to get the access_token and where to store it. How to pass post parameter of POST https://github.com/login/oauth/access_token such as client_id, scope, code in my django view. And how to link different access for different user. Please help me. I am having problem in getting the basics right.
I recommend using Python Social Auth and then leveraging their Github backend after setting it up to work with your django app.
So, you would roughly be able to pass the access token using something like:
import requests
user = User.objects.get(...)
social = user.social_auth.get(provider='github')
response = requests.get(
'https://github.com/login/oauth/authorize?
client_id=something&scope=something,something',
params={'access_token': social.extra_data['access_token']}
)
retrieved_data = response.json()['items']
You can also make the token available in your template if you'd like to continue using a link. And, you don't need to pass the scope as a query parameter, certainly, Python Social Auth can also handle that for you

How to create an API with a "remember me" function in Flask?

I'm going to build an API in Flask for a (to be created) app which will be built using PhoneGap. In the API many calls will need authentication.
To get into the topic I was reading this tutorial on creating authentication for a Flask-built API. In this tutorial they first show how a user can use basic password authentication for every call, after which token based authentication is introduced.
As far as I understand, the client who calls the API should simply get a token and authenticate every subsequent call with that. In the meantime, the client should keep track of time and either get a new token every 9 minutes (before the old token expires) or simply keep on calling with the token until the client gets an Unauhorized Access message. Am I understanding this correctly?
Moving on, I wonder how it works with Apps on which you login on your phone and then are always logged in whenever you open the app (like for example the Facebook app). This is obviously more convenient to the user than always needing to provide the username/password and I would like to implement something like that as well. I wonder though; how is a permanent logged in feature like this implemented on the server side? Is it done by providing the password and username for every call, or using a never expiring token, or yet a different way?
All tips are welcome!
I've done what you want to do with:
Flask-security https://pythonhosted.org/Flask-Security/:
To manage users and permissions.
Flask-oauth-lib https://flask-oauthlib.readthedocs.org/en/latest/:
Provide oauth functionnality.
So, you have to take a look at Oauth flow, implements a user backend (like Flask-security) and implements an oauth server (with flask oauth lib for example) and bind it to your user backend.
After that, it's oauth standard flow. You just have to give the right token on each api calls and TADA !
With this way you can also, if you want, give access to your api to third-party app thanks to oAuth :)

Categories

Resources