How to generate user access token from active directory token? - azure-active-directory

We are using custom web api and angular as a front-end. We already have active directory access token and we need to access SharePoint lists under user context. How to use azure active directory token to generate user access token to access SharePoint on behalf of Flow?

To use the acquired access_token to request new access_token from another API, you could use the on_behalf_of flow.
For V2 enpoint, the request URL:
https://login.microsoftonline.com//oauth2/v2.0/token
POST /oauth2/token HTTP/1.1
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded
grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer
&client_id=<application-id>
&client_secret=<key value>
&assertion=<acquired access_token>
&requested_token_use=on_behalf_of
&scope=https://graph.microsoft.com/User.Read email(here the example API is [ms graph API][1], and the permissions are User.Read and email)
For the details, you could refer to this dos.

Related

Graph API Not able to access "https://graph.microsoft.com/v1.0/me/messages" endpoint

I am trying to access "https://graph.microsoft.com/v1.0/me/messages" API by JAVA SDK provided by Microsoft.
I am using the below code.
final AuthorizationCodeCredential authCodeCredential = new AuthorizationCodeCredentialBuilder()
.clientId("b****08f-*****-4d49-****-cba7d9a****c")
.clientSecret("8***7Q~GW0N******Y_N*****Zi******")
.authorizationCode("0.AVUAoIQSV...")
.redirectUrl("http://localhost/auth-responses")
.build();
Now it is giving me error like "The tenant for tenant guid '571284a0---****-a94eea6c6b3f' does not exist."
I tried the Same thing by postman, here I tried to get token by below end point.
"https://login.microsoftonline.com/common/oauth2/token"
after getting the token I am using it in "https://graph.microsoft.com/v1.0/me/messages" as Bearer Token. Still, I am getting the same issue.
But the token I am receiving in every case is not same as graph explorer Access Token
If I copy Graph Explorer Access Token and use it in postman then it gives me the desired result.
I am using a personal account for all of this process which ends with "#outlook.com".
I want to know why I am getting different access tokens than graph explorer access tokens and why that access token is not able to access the endpoints.
I have tested in my environment.
The access token generated from the Graph Explorer will be different from the access token generated from the Postman. This is because, the access token generated from graph explorer uses only the user credentials. The access token generated from postman uses client id and the client secret along with user credentials.
If the app registration supports Accounts in any organizational directory (Any Azure AD directory - Multitenant) and personal Microsoft accounts (e.g. Skype, Xbox), then only you can use personal account to generate the access token and use it to call the request for https://graph.microsoft.com/v1.0/me/messages only if the app registration have Microsoft Graph mail.read delegated permissions.
Paste the below URL in the browser. The code will be generated. Copy the code.
https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/authorize?
client_id=app-client-id
&response_type=code
&response_mode=query
&scope=mail.read
Make the below POST request in the postman to generate the access token :
POST https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/token
Headers :
Content-Type: application/x-www-form-urlencoded
Body :
client_id: App Client ID
grant_type: authorization_code
scope: user.read%20mail.read
code: Code received in the first step
client_secret: Client Secret Generated in the App
Copy the Access token and make the below get request in the postman to read the messages :
GET https://graph.microsoft.com/v1.0/me/messages
Headers:
Authorization : Bearer access-token

Azure API Authentication and MSGraph

I am looking into a Node.JS API that has authentication through Azure AD, which all seems to be working ok, when i pass access token generated by logging into the web app, it authenticates and returns data.
However i now need the API to access MSGraph to retrieve Profile Photo etc. Ho do i pass authentication to MSGraph, i believe the accesstoken is different isnt it because they are different scopes. So how do i generate a new accesstoken for MSGrpah after i have logged into my app.
API endpoint just queries a db of users returning a JSON response, but i want to append the users profile image in base64Image to the response.
How do i do this
Thanks
You could use On-Behalf-Of flow, the OAuth 2.0 On-Behalf-Of flow (OBO) serves the use case where an application invokes a service/web API, which in turn needs to call another service/web API.
Sample:
POST /oauth2/v2.0/token HTTP/1.1
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded
grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer
&client_id=2846f71b-a7a4-4987-bab3-760035b2f389
&client_secret=BYyVnAt56JpLwUcyo47XODd
&assertion=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6InowMzl6ZHNGdWl6cEJmQlZLMVRuMjVRSFlPMCJ9.eyJhdWQiOiIyODQ2ZjcxYi1hN2E0LTQ5ODctYmFiMy03NjAwMzViMmYzODkiLCJpc3MiOiJodHRwczovL2xvZ2luLm1pY3Jvc29mdG9ubGluZS5jb20vNzJmOTg4YmYtODZmMS00MWFmLTkxYWItMmQ3Y2QwMTFkYjQ3L3YyLjAiLCJpYXQiOjE0OTM5MjA5MTYsIm5iZiI6MTQ5MzkyMDkxNiwiZXhwIjoxNDkzOTI0ODE2LCJhaW8iOiJBU1FBMi84REFBQUFnZm8vNk9CR0NaaFV2NjJ6MFFYSEZKR0VVYUIwRUlIV3NhcGducndMMnVrPSIsIm5hbWUiOiJOYXZ5YSBDYW51bWFsbGEiLCJvaWQiOiJkNWU5NzljNy0zZDJkLTQyYWYtOGYzMC03MjdkZDRjMmQzODMiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJuYWNhbnVtYUBtaWNyb3NvZnQuY29tIiwic3ViIjoiZ1Q5a1FMN2hXRUpUUGg1OWJlX1l5dVZNRDFOTEdiREJFWFRhbEQzU3FZYyIsInRpZCI6IjcyZjk4OGJmLTg2ZjEtNDFhZi05MWFiLTJkN2NkMDExZGI0NyIsInV0aSI6IjN5U3F4UHJweUVPd0ZsTWFFMU1PQUEiLCJ2ZXIiOiIyLjAifQ.TPPJSvpNCSCyUeIiKQoLMixN1-M-Y5U0QxtxVkpepjyoWNG0i49YFAJC6ADdCs5nJXr6f-ozIRuaiPzy29yRUOdSz_8KqG42luCyC1c951HyeDgqUJSz91Ku150D9kP5B9-2R-jgCerD_VVuxXUdkuPFEl3VEADC_1qkGBiIg0AyLLbz7DTMp5DvmbC09DhrQQiouHQGFSk2TPmksqHm3-b3RgeNM1rJmpLThis2ZWBEIPx662pjxL6NJDmV08cPVIcGX4KkFo54Z3rfwiYg4YssiUc4w-w3NJUBQhnzfTl4_Mtq2d7cVlul9uDzras091vFy32tWkrpa970UvdVfQ
&scope=https://graph.microsoft.com/user.read+offline_access
&requested_token_use=on_behalf_of

Client Credential Gran Type Not Support with a Custom B2C Policy

I am trying to generate an access token from our policy but I am getting this error.
AADB2C90086: The supplied grant_type [client_credentials] is not supported.
This is a sample postman request
POST /{tenant}/oauth2/token?p=B2C_1A_SignUpOrSignInWithAAD HTTP/1.1
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded
Cache-Control: no-cache
grant_type=client_credentials&client_id={client_id}&resource=https%3A%2F%2F{app_url}&client_secret={client_secret}
but it works fine if I don't use our custom policy and just go direct to the B2C tenant
POST /{tenant}/oauth2/token?api-version=1.0
... same as above
Is there something missing in our custom policy?
B2C does not support the Client Credential Flow. Additional details are here. And here Daemons/server-side apps.
but it works fine if I don't use our custom policy
That's because you getting a token from Azure AD, not B2C.

Can service/daemon app use 'common' instead of 'tenant-id' when obtaining token from Azure AD v2.0 endpoint

I am developing a daemon app that can perform actions on user inboxes in multiple tenants. Once an admin from a tenant gives the app the required permissions, it should be able to access users inboxes in that tenant. I am doing the following now.
Get consent from admin
https://login.microsoftonline.com/common/adminconsent?client_id={client-id}&redirect_uri=https%3A%2F%2Fredirect.test.com
Global Admin from a tenant (e.g. myutils.onmcirosoft.com) gives required permission.
Get access token by using common instead of tenant-id
curl -X POST _https://login.microsoftonline.com/common/oauth2/v2.0/token --data "grant_type=client_credentials&client_id={client-id}&client_secret={clientsecret}&scope=https://graph.microsoft.com/.default
It gives a access token.
Access messages of admin#myutils.onmicrosoft.com using the token obtained in step 3.
curl -X GET -H "Authorization: Bearer <token>" https://graph.microsoft.com/v1.0/users/admin#myutils.onmicrosoft.com/messages
Above curl request gives the following 404 response:
HTTP/1.1 404 Not Found
Cache-Control: private
Transfer-Encoding: chunked
Content-Type: text/plain
request-id: e602ada7-6efd-4e18-a979-63c02b9f3c76
client-request-id: e602ada7-6efd-4e18-a979-63c02b9f3c76
x-ms-ags-diagnostic: {"ServerInfo":{"DataCenter":"West US","Slice":"SliceB","ScaleUnit":"000","Host":"AGSFE_IN_22","ADSiteName":"WST"}}
Duration: 1537.3097
Date: Tue, 19 Sep 2017 09:31:08 GMT
In step 3 if I replace common with tenant-id of myutils.onmicrosoft.com it is working.
Is common supported with Azure AD v2.0 endpoint? This link says common is not supported for v1 endpoint. Is it the same for v2.0 endpoint as well?
Just to expand on Nan Yo's answer, the reason you need the tenant-id is due to Graph API itself being a multi-tenant.
Without a tenant-id, Graph would have no way of knowing which tenant to route your calls too. For example,/users returns a list of users but without a tenant-id there is no way to determine which tenant it should pull the users from.
When you use authorization_code or implicit grants, it uses the user's credentials to determine which tenant calls should be routed too. With client_credentials you don't have those credentials to pull those routing queues from.
You can however determine the tenant id during Admin Consent. Along with the admin_consent result, it also returns the tenant. For a multi-tenant service you would need to store that id to use when obtaining a token prior to making a call to Graph.
When using the client credentials flow in Azure AD V2.0, you need to specify the actual tenant that you want a token for. Otherwise , even you get an access token , you will find no application roles include in the access token . An access token will issued from one tenant and could access resource of that tenant , it is impossible to use one access token to query resources of multi tenants .
Please acquiring your token not from /common/oauth/v2.0/token endpoint , use /{tenent-id}/oauth2/v2.0/token endpoint with the tenant id .
Please click here for more details .

Postman - how to obtain Azure Active Directory token using sign in form?

Is is possible to obtain an AAD token in Postman by letting the user to Sign In using the standard AAD sign in form?
I know how to obtain token using the request to AAD (grant_type = client_credentials) but such a token does not have a UPN (user identity).
I would like to somehow type in my credentials in Postman and get the token. So it is a manual interaction, the user(me) needs to manually sign in - the same way how ie. Visual Studio verifies your identity.
Postman now offers the ability to "Authorize using browser." You'll need to make changes to your AAD application to support it in addition to configuring Postman.
Configure your AAD application
Add a redirect URI to your AAD application for Postman to receive the authorization code. In the AAD Portal, navigate to your app registration, then to the "Authentication" tab, then add https://oauth.pstmn.io/v1/callback as a new redirect URI. This URI was provided by Postman when you check the ✅ Authorize using browser box (below) and is also documented on their website.
Configure Postman
You can set this up under "Authorization" for a single request, a folder of requests, or a Collection. Open the "Authorization" tab and select OAuth 2.0. Under the "Configure New Token" section, enter the following information:
Token Name: anything you want. I chose the name of the AAD application.
Grant Type: Authorization Code (With PKCE)
Callback URL: check the ✅ Authorize using browser box
Auth URL: copy this from the AAD portal under Overview > Endpoints (on top bar) > OAuth 2.0 authorization endpoint (v2). Mine looks like https://login.microsoftonline.com/<tenant>/oauth2/v2.0/authorize
Access token URL: copy this from the AAD portal under Overview > Endpoints (on top bar) > OAuth 2.0 token endpoint (v2). Mine looks like https://login.microsoftonline.com/<tenant>/oauth2/v2.0/token
Client ID: copy this from the AAD portal under Overview. It's also commonly referred to as an "Application ID" and is a GUID.
Client Secret: leave blank (not used by this grant type)
Code Challenge Method: SHA-256
Code Verifier: leave blank or provide your own
Scope: the scopes you're requesting in your token, separated by spaces
State: leave blank or provide a value such as a random GUID.
Client Authentication: Send as Basic Auth Header (not used by this grant type)
Refer to Postman's documentation on OAuth 2.0 options for more information.
Get a token
Click Get New Access Token to open the auth flow in your machine's default web browser. After authentication, it should redirect back to the Postman application and a new token will be created with the name you provided earlier for "Token Name." Select "Use Token" in the top-right corner of the popup to copy it into your current token. If the token expires and your requests start failing authorization (probably a 401 or 403 error), you can revisit this tab and get a new access token.
Occasionally, you may want to visit Current Token > Access Token > Manage Tokens > Delete > Expired tokens, otherwise you'll be inundated with nearly-identical tokens.
Postman cannot popup the sign in page as it only does HTTP requests. As you stated, it can do confidential client flows.
What you could do is hand-construct an auth request, sign in, and grab the auth code. Then take that auth code and drop it into the Postman authorization form, and let it hit the Azure AD token endpoint:
https://login.microsoftonline.com/common/oauth2/v2.0/token
The Azure AD protocol referene will be super helpful for you.
I think if you're wanting to quickly generate Access Tokens your best bet is to pick a framework/language and build a lightweight app that gets and logs tokens. Azure AD has a Python Flask sample for the v2 endpoint that takes 5 minutes to setup and could be converted to printing out access tokens. If you want to use v1, you can checkout the list of samples at the Azure AD developer guide.

Resources