I am trying to use an App Registration to get a Token Bearer, but I don't have idea on how to do that using App registration. I have this in postman:
As far as I know, after you register an application (web,mobile app...) in Identity Server (Microsoft in this case), you will get client_id and client_secret --> This is grant-types: client-credentials https://www.oauth.com/oauth2-servers/access-tokens/client-credentials/
If you want to use grant-types: password, you also need client_id and client_secret to ask for access_token. https://www.oauth.com/oauth2-servers/access-tokens/password-grant/
Your parameter is not assigned, and you need to select the Content-Type as: x-www-form-urlencoded, the complete request is as follows:
Related
I have this Authorization request that works.
How can I replicate it in Python?
I am using an Azure AD to authenticate the access.
Since you are working with python, your case is a : Oauth2 login for SSR web applications with Microsoft
Goal
Get an access_token from interactive login using the oauth2 authorization code grant
Steps
Here I will list all the steps required to do it with any language
Create a web with session with at least these endpoints
/ : home page
/callback : server route or path able to receive query params like /callback?code=123456. This along with your base domain will be called redirect_uri. Sample : http://localhost:8080/callback or http://acme.com/callback
Create and configure an app in Azure Dev Console. Same process is in Google, Facebook, Linkedin, etc. As a result you should have a clientId, clientSecret and a redirect url
Create a simple web with classic session in which if user is not logged-in, redirect (302) to this url:
https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=foo&response_type=code&redirect_uri=foo&response_mode=query&scope=offline_access%20user.read%20mail.read
clientid and redirect_uri are important here and should be the same of previous step
After that, browser should redirect the user to the platform login
If user enters valid credentials and accepts the consent warning, Microsoft will perform another redirect (302) to the provided redirect_uri but with special value: The auth code
http://acme.com/callback?code=123456798
In the backend of /callback get the code and send it to this new endpoint
Add a client_id & client_secret parameters
Add a code parameter with the code sent by microsoft
Add a redirect_uri parameter with previously used and registered on azure. Sample http://acme.com/callback or http://localhost:8080/callback
Add a grant_type parameter with a value of authorization_code
Issue the HTTP POST request with content-type: application/x-www-form-urlencoded
You should get a response with the precious access_token:
{
token_type: 'Bearer',
scope: 'Mail.Read User.Read profile openid email',
expires_in: 5020,
ext_expires_in: 5020,
access_token: 'eyJ0oVlKhZHsvMhRydQ',
refresh_token: 's_Rcrqf6xMaWcPHJxRFwCQFkL_qUYqBLM71UN6'
}
You could do with this token, whatever you configured in azure. Sample: If you want to access to user calendar, profile, etc on behalf of the user, you should have registered this in the azure console. So the clientid is related to that and human user will be prompted with something like this
Libraries
There is some libraries provided by microsoft (c#, nodejs) which will save you a little work. Anyway the previous explanation are very detailed.
Advice
Read about oauth2 spec: https://oauth.net/2/
Read about oauth2 authorization code flow login before the implementation with python
https://www.digitalocean.com/community/tutorials/an-introduction-to-oauth-2
https://auth0.com/docs/get-started/authentication-and-authorization-flow/authorization-code-flow
https://github.com/msusdev/microsoft_identity_platform_dev/blob/main/presentations/auth_users_msalnet.md
Check this to understand how configure the azure web console: https://learn.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app
Check my gist https://gist.github.com/jrichardsz/5b8ba730978fce7a7c585007d3fd06b4
Just starting to work with SharePoint and Microsoft authentication and trying to get a SharePoint List into a JavaScript App. From Microsoft documentation, I need to use the following:
GET https://{site_url}/_api/web/lists/GetByTitle('List Title')
Authorization: "Bearer " + accessToken
Accept: "application/json;odata=verbose"
Have searched everywhere to find an definitive answer to how to obtain this accessToken. All the documentation I can find from Microsoft seem to be out of date. Does anyone know the current method to obtain an accessToken?
To call SharePoint specific APIs you need to get a SPO specific access token. You can "swap" an regular MS Graph refresh token for an SPO specific token by doing the following:
Get a delegated auth token from graph as you normally would
(https://learn.microsoft.com/en-us/graph/auth-v2-user)
Use the refresh_token you got and exchange it for an SPO access token by calling the auth endpoint again:
POST https://login.microsoftonline.com/{{tenantName}}/oauth2/v2.0/token
With the following form data:
client_id=<APP ID>
client_secret=<APP SECRET>
refresh_token=<REFRESH TOKEN FROM ABOVE>
grant_type=refresh_token
scope=https://<YOUR TENANT NAME>.sharepoint.com/Sites.Read.All
Take the access token and call the SPO API
You must ensure your app is registered with the correct permissions. In the case above the app must have Sites.Read.All for example.
You could refer to this article to get access token:
https://global-sharepoint.com/sharepoint-online/in-4-steps-access-sharepoint-online-data-using-postman-tool/
Post https://accounts.accesscontrol.windows.net/<Tenant ID>/tokens/OAuth/2
Body:
grant_type client_credentials
client_id <Client ID>
client_secret <Client Secret>
resource 00000003-0000-0ff1-ce00-000000000000/<tenant>.sharepoint.com#<Tenant ID>
My test result:
There is not much documentation for SP API, but it still works. You may follow documentation to get token for Graph API by whatever type of authentication is suitable for your scenario, but instead of passing scopes for Graph API (which is "https://graph.microsoft.com/.default"), you should pass scopes for Sharepoint API which is "https://{your tenant name}.sharepoint.com/.default"
".default" will provide you the access with all permissions which was assigned in Azure AD - so also make sure, that Azure admin has granted you required API permissions for SharePoint API.
This will also work for MSAL.
Should a OAuth 2.0 Client send his client_id and client_secret only at his initial request for authorization?
Or at every request he sends to the Authorization/Resource-Server?
Thanks in advance!
#Edit 1: We try to implement the 'Resource Owner Password Credentials'-Flow.
#Edit 2: My guess is that you dont need to send it after you aquired the Access Token. Cause when you already have the access token, the client sends his request directly to the Resource Server. But if you need a refresh token and request one from the Authorization Server, then you need to send client_id and client_secret too. Or am i mistaken?
It all depends on what you want to do with oauth (the flow you use).
You should refer to the flows described here :
https://www.rfc-editor.org/rfc/rfc6749
The client_id is required when you redirect to the authorization endpoint of the authorization server. The secret is used when you exchange an authorization code with the authorization server.
Then you should send your access token at every request of your client with your resource server (api) using the header "authorization"
I am making OAuth 2.0 auth code authentication flow with multi-tenant application.
Here is my authorize url:
https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=my_id&prompt=consent&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fauthorize&response_type=code&scope=openid+offline_access&state=17
It goes fine and I receive auth_code. Then I make request with this auth_code to token_url and receive a lot of information, like:
token_type
scope
id_token
access_token
refresh_token
expires_at
ext_expires_in
Seems fine to me, but when I make request on API with access_token like:
https://management.azure.com/subscriptions/my_sub_id/locations?api-version=2016-06-01
with headers:
Content-Type:
- application/json
Authorization:
- Bearer EwBQA8l6BAAURSN/FHlDW5xN74t6GzbtsBBeBUYAAV1IHgHb4dOWblzfd/YsSuFicAMDYbua17QivnAT9/pIaeKAg3uKsK5VGqWLzjMOUQrCpd7R1RAM6RkzI0u8e4rpO7DISG7qLso5H5+U1jb+38/j1urcwlXMMxhy83ZXmdpkLXpZV+vcOV...
It responds with 401 error
body:
encoding: UTF-8
string: '{"error":{"code":"InvalidAuthenticationToken","message":"The access token is invalid."}}'
To be honest I think something wrong with my access_token. It seems not like JWT for me. Documentation says it looks like:
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCEV1Q..."
But my access_token looks like:
"access_token": "EwBYA8l6BAAURSN/FHlDW5xN74t6GzbtsBBeBUYAAZDe7JE/MPLoAi+Fr+1Xxq5eBe5N9l8Q+c4QjkY5PGEzRnBpPe7+v6h+PLdh1cceBQx+/JsB2QCrYSCt7x/zGsQAhwoY/"
Is it fine?
Here is my permissions for application:
Permissions
The main issue you have here is that you have only asked for an access token for the scopes openid offline_access. The resulting access token will be for Microsoft Graph (https://graph.microsoft.com), not for the Azure REST API (https://management.azure.com).
To indicate you would like a token for a given API, the scope parameter in your authorization request should include the delegated permission you would like the app to have for the API. In the case of Azure REST API, there's only one delegated permission: user_impersonation. The identifier URI for the Azure REST API is https://management.azure.com, so the scope value you want to use is:
openid offline_access https://management.azure.com/user_impersonation
Two more important notes:
As you've discovered, you will not always be issued an access token as a JWT which you can decode peek at. The format of the access token is an agreement between the service which issued the token (Azure AD or Microsoft Accounts, in this case), and the service for which the token was issued (Microsoft Graph, in this example).
You should not always include prompt=consent. prompt=consent should only be used if you have already tried signing in the user without the user needs to be re-prompted for consent for a new permission.
If you simply include the required scopes in the scopes parameter, the Microsoft Identity platform will take care of figuring out if it needs to prompt for consent or not. If you always include prompt=consent, you will find that many organizations will be blocked from accessing your app, because they've disabled the ability for users to grant consent themselves (and this parameter specifically states that you require the user to be prompted again).
How to login with username/password (end-user credentials) using OAuth2 and Microsoft login
https://login.microsoftonline.com/{app-id}/oauth2/token
Microsoft does not recommend passing username/password information for endusers. That is why they dont post guides for this. For security reason they want you to use the redirection to their login page. Use https://login.microsoftonline.com/{tenant-id}/oauth2/authorize to get there.
However it is possible and very easy to do this using their oauth2 rest api.
Create an http request to
base url: https://login.microsoftonline.com/{tenant-id}/oauth2/token
{tenant-id} //obtained from AzureAD config section
Use the following request parameters in the body section
grant_type = password //read up on the other grant types, they are all useful, client_credentials and authorization_code
client_id = {client-id}//obtained from the application section in AzureAD
client_secret = {client-secret}//obtained from the application section in AzureAD
resource = https://graph.microsoft.com //there is also the api https://graph.windows.net, use the latest and best one
username = {enduser-username} //example rofler#domain.onmicrosoft.com
password = {enduser-password} //example Hs782f8a
A successful response should include the access_token and refresh_token
Tested in year 2016
Recommended links
Postman
Microsoft Graph
Windows Graph