I'm trying to integrate D365FO with a third party application, I was able to do the proper setup and register my app, fetch the Token as shown below:
I used the resource as the link for D365FO at the development machine, which is https://usnconeboxax1aos.cloud.onebox.dynamics.com/ and read the D365FO data as shown below:
I want to change the login methid, so I do login on behalf of the user, using the password, so I Disabled thesecurirty details at Azure (based on this), as below:
And got teh token of the loged user successfult as below:
But once I tried fetching the same data which I was able to fetch before, I got 401 unauthorized, though I'm loggin in using the Admin account:
The error 401 Unauthorized usually occurs if you make calls to the resource with invalid audience.
When you generate the access token with scope as user.read openid profile offline_access, audience will be Microsoft Graph that won't work with D365FO.
I tried to reproduce the same in my environment via Postman and got below results:
I registered one Azure AD application and added same API permissions like below:
Now I generated tokens with grant type as password by including same parameters as you like below:
POST https://login.microsoftonline.com/organizations/oauth2/v2.0/token
client_id: <appID>
client_secret: <secret>
scope: user.read openid profile offline_access
grant_type: password
username: admin#xxxxxxxxx.onmicrosoft.com
password: xxxxxxxxxxx
Response:
You can decode the above access token by pasting it in jwt.ms to check the audience.
When I decoded the access token, I got aud claim as 00000003-0000-0000-c000-000000000000 (i.e, Microsoft Graph) like below:
If you use this token to read D365FO data, you will get 401 Unauthorized error as audience is invalid.
To resolve the error, you need to generate access token with resource value as base URL of your D365FO instance by making below changes:
POST https://login.microsoftonline.com/organizations/oauth2/token
client_id: <appID>
client_secret: <secret>
resource: <base URL of your D365FO instance without the trailing '/'>
grant_type: password
username: admin#xxxxxxxxx.onmicrosoft.com
password: xxxxxxxxxxx
In your case, value of resource parameter should be https://usnconeboxax1aos.cloud.onebox.dynamics.com
This token will have audience same as your D365FO root URL. To confirm that, you can decode it in jwt.ms. If you use this token to read D365FO data, it will work!
Reference:
Test services by using third-party utilities - Finance & Operations | Dynamics 365 | Microsoft
Related
I am using the example msal-react to authenticate and consume sharepoint services using their graph api, create an application on AAD with delegated permissions.
I am assigning the scopes "https://mytenant.sharepoint.com/.default" and I get the following error code: "InvalidAuthenticationToken" message: "Access token validation failure. Invalid audience." check the token I get on the JWT.io page .
Thank you very much for your support
You are using the graph API to perform CRUD operations for SharePoint sites, so you should get an access token for the graph API instead of the SharePoint REST API.
So please change your scope to: https://graph.microsoft.com/.default.
I tried to reproduce the same in my environment via Postman and got below results:
I registered one SPA application and added SharePoint API permissions like below:
I generated access token via Postman with below parameters:
POST https://login.microsoftonline.com/<tenantID>/oauth2/v2.0/token
client_id:appID
grant_type:authorization_code
scope: https://mytenant.sharepoint.com/.default
code:code
redirect_uri: https://jwt.ms
code_verifier:S256
Response:
When I decoded the token, it has SharePoint as audience and scp claim as below:
I got the same error as you when I used above token to call SharePoint from below graph API call:
GET https://graph.microsoft.com/v1.0/sites/<siteID>/lists
Response:
To resolve the error, assign Microsoft Graph API permissions for SharePoint like below:
Now, generate the access token again by changing the scope to https://graph.microsoft.com/.default as suggested by #Carl Zhao like below:
POST https://login.microsoftonline.com/<tenantID>/oauth2/v2.0/token
client_id:appID
grant_type:authorization_code
scope: https://graph.microsoft.com/.default
code:code
redirect_uri: https://jwt.ms
code_verifier:S256
Response:
When I decoded the above token, I got Microsoft Graph as audience and scp claims are as below:
When I used above token to call SharePoint site lists from below graph API call, I got the results successfully like below:
GET https://graph.microsoft.com/v1.0/sites/<siteID>/lists
Response:
Note that, your token audience should be https://graph.microsoft.com while making graph calls and scp claim should contain Microsoft graph permissions.
I am working on my first project of connecting Azure B2C with MERN App. I wanted to Sign In using Azure B2C and authorise my web API using the Access Token.
I configured everything and applied configurations to this sample React tutorial provide by their documentation.
The problem arises while calling the Web API. The Web API call are sending without any token. When I check the code, acquireTokenSilent function returning empty accessToken from response.
instance.acquireTokenSilent({
scopes: protectedResources.apiHello.scopes,
account: account
}).then(async (response) => {
console.log(response)
The Request is:
Even though I looked many forums and Microsoft technical forums, no answer is not working.
But what I noticed is, it is requesting for grant_type: authorization_code but am not seeing access token in the response. Posting here the API call, request and response.
The Response is producing id_token but not access token,
I gave grant permission in the SPA App permission for task.read scope. I tried everything but I am still receiving the access token as empty. How could I fix this issue?
I tried to reproduce the same in my environment and got below results:
I registered one Azure AD B2C application for app1 and added scopes(task.read) as below:
Now I created one SPA registration and added API permissions by granting consent like this:
I created Sign up and sign in policy and ran the user flow as below:
Please Check authentication and access token and id token:
I signed in as user it gave me auth code in address bar.
https://<tenant name >.b2clogin.com/<tenant name> .onmicrosoft.com/oauth2/v2.0/authorize?p=B2C_1_susi&client_id=<app id>&nonce=defaultNonce&redirect_uri=https://jwt.ms&scope=openid%20https%3A%2F%2F<tenant name>.onmicrosoft.com tasks.read&response_type=code&prompt=login&code_challenge_method=S256&code_challenge=<challenge paramater>
I generated the access token via Postman with commands like this:
POST https://tenant.b2clogin.com/tenant.onmicrosoft.com/policy/oauth2/v2.0/token
grant_type: authorization_code
client_id: SPA_appid
scope: https://tenant.onmicrosoft.com/app1/task.read
redirect_uri: redirect_uri
code: code
code_verifier: code_verifier
Postman
When I decode the token i getting scp in jwt .ms
In my java web application I want to get access to user's mailbox by using jakarta mail. For that purpose I followed https://learn.microsoft.com/en-us/exchange/client-developer/legacy-protocols/how-to-authenticate-an-imap-pop-smtp-application-by-using-oauth for OAuth2 authorization code flow.
On Azure port I setup my app and added API permissions as below
Now user is redirecting to below authorize endpoint:
https://login.microsoftonline.com/5426ee07-9b73-4a9e-8075-395ab439c6fa/oauth2/v2.0/authorize?client_id=b6067ad9-7195-430b-a35d-97b7aa7beb8f&response_type=code&redirect_uri=http://localhost:8080/callback/microsoft&response_mode=query&scope=offline_access%20https%3A%2F%2Fgraph.microsoft.com%2FIMAP.AccessAsUser.All%20https%3A%2F%2Fgraph.microsoft.com%2FSMTP.Send
After entering credentials and accepting the consent redirect_uri gets hit with auth code. Based on that auth code I formed token endpoint URL and hitting it from server, the token endpoint is as follow:
URL: https://login.microsoftonline.com/5426ee07-9b73-4a9e-8075-395ab439c6fa/oauth2/v2.0/token
Form Data:
client_id=b6067ad9-7195-430b-a35d-97b7aa7beb8f
scope=offline_access%20https%3A%2F%2Foutlook.office.com%2FIMAP.AccessAsUser.All
redirect_uri=http://localhost:8080/callback/microsoft
grant_type=authorization_code
client_secret=QUs8Q~aboLBiopTezMTKwzQjIwWsFFXjc2kCRaRs (I know I have shared the secret)
code={code received from authorize end point}
Response to this post request comes as:
{"error":"invalid_grant","error_description":"AADSTS65001: The user or administrator has not consented to use the application with ID 'b6067ad9-7195-430b-a35d-97b7aa7beb8f' named 'Email Connector'. Send an interactive authorization request for this user and resource.\r\nTrace ID: dc008ced-e23f-4919-bd45-b7ae7c68b000\r\nCorrelation ID: 9b6ede03-3c05-4a78-8975-036a3cb20773\r\nTimestamp: 2022-06-07 19:51:30Z","error_codes":[65001],"timestamp":"2022-06-07 19:51:30Z","trace_id":"dc008ced-e23f-4919-bd45-b7ae7c68b000","correlation_id":"9b6ede03-3c05-4a78-8975-036a3cb20773","suberror":"consent_required"}
Here, I don't understand why the error is saying The user or administrator has not consented to use the application, user has accepted the consent after entering credentials on authorize end point. Event more If we look at the screenshot above admin has already given grant to access the directory.
I tried to reproduce the same scenario in my environment and got the same error as below:
To resolve the error, please check the authorize endpoint you are using to get the code.
Avoid using Microsoft graph API scopes while getting the code.
Replace it with the scope you are using to get access token like below:
https://login.microsoftonline.com/Your_TenantID/oauth2/v2.0/authorize?
client_id=Your_ClientID
&response_type=code
&redirect_uri=http://localhost:8080/callback/microsoft
&response_mode=query
&scope= offline_access https://outlook.office.com/IMAP.AccessAsUser.All
&state=12345
Get the code from the above authorization endpoint.
I got the access token successfully after modifying the endpoint like below:
To validate the access token decode it in jwt.io and check the aud and scp claims like below:
I have error "Access token validation failure. Invalid audience."
For application set api permissions to offline_access, openid, profile, User.Read.
User start auth, go to MS auth site, ask about login, password and grand.
After exchange code to access token i well receive
{'token_type': 'Bearer', 'scope': 'offline_access openid profile User.Read', 'expires_in': '3906', 'ext_expires_in': '3906', 'expires_on': '1653988700', 'not_before': '1653984493', 'resource': 'my_azure_client_id', ....}
Then i try get profile for current user with this access token.
As result i have error "Access token validation failure. Invalid audience."
Help pease)
UPDATE
Configured permissions
The reason behind getting that error is because your token has wrong audience.
Please check what token you are using to call Graph API.
I tried to reproduce the same in my environment.
If you are using ID Token instead of Access Token, you may get error like below:
To know whether you are giving access token or id token, decode it in JSON Web Tokens - jwt.io.
For access token, aud claim will be "https://graph.microsoft.com" or "00000003-0000-0000-c000-000000000000"
For id token, aud claim will be "your_app_client_id"
Choose the access token carefully with aud as "https://graph.microsoft.com" while calling Microsoft Graph API:
To get profile for current user, you can make use of below query:
GET https://graph.microsoft.com/v1.0/me
I got the profile successfully using access token like below:
Replace your scope with https://graph.microsoft.com/.default while generating access token to avoid confusion.
Reference:
oauth 2.0 - Microsoft Graph API: Access token validation failure. Invalid audience - Stack Overflow
UPDATE:
In order to get authorization code, make the request by changing scope like below:
https://login.microsoftonline.com/your_tenant_id/oauth2/v2.0/authorize?
client_id=your_client_id
&response_type=code
&redirect_uri=xxxxxx
&response_mode=query
&scope=https://graph.microsoft.com/.default
&state=12345
I have registered a multitenant app at https://apps.dev.microsoft.com since the "admin consent" prompt wasn't available in the Azure AD apps. Admin consent is required for our app to retrieve info about users and their calendars.
I can provide admin consent from a completely different tenant than what this app is registered from and use the provided access token to retrieve all necessary information, however that obviously expires after an hour and we need offline access.
I have tried using the tenantId instead of 'common' in the https://login.windows.net/common/oauth2/token endpoint, however receive the same message as below.
The following is the data being submitted to the token endpoint in json format (converted within node to form encoded format before submitting):
{
grant_type: 'refresh_token',
client_id: 'e5c0d59d-b2c8-4916-99ac-3c06d942b3e3',
client_secret: '(redacted)',
refresh_token: '(redacted)',
scope: 'openid offline_access calendars.read user.read.all'
}
When I try to refresh the access token I receive an error:
{
"error":"invalid_grant",
"error_description":"AADSTS65001: The user or administrator has not consented to use the application with ID 'e5c0d59d-b2c8-4916-99ac-3c06d942b3e3'. Send an interactive authorization request for this user and resource.\r\nTrace ID: 2bffaa08-8c56-4872-8f9c-985417402e00\r\nCorrelation ID: c7653601-bf96-46c3-b1ff-4857fb25b7dc\r\nTimestamp: 2017-03-22 02:17:13Z",
"error_codes":[65001],
"timestamp":"2017-03-22 02:17:13Z",
"trace_id":"2bffaa08-8c56-4872-8f9c-985417402e00",
"correlation_id":"c7653601-bf96-46c3-b1ff-4857fb25b7dc"
}
This error occurs even when standard consent is used. I have also tried using the node-adal library instead of raw http requests which produces the exact same result.
I note that "offline_access" isn't a permission I am able to set within the MS apps portal, however I would guess the fact that I am getting a refresh token back means that I can refresh the access token?
For the record, the following is the node-adal code I used to see if I was doing something wrong:
var self = this;
var authenticationContext = new AuthenticationContext('https://login.windows.net/common');
authenticationContext.acquireTokenWithRefreshToken(
self.refreshToken,
self.clientId,
self.clientSecret,
'https://graph.microsoft.com/',
function(a) {
console.log(a);
}
);
Any help in getting this refresh process working is appreciated!
Please ensure that the tenant that you using for refreshing token is same as the tenant that you requesting for the access_token.
The refresh token request works well for me unless in the scenario of below:
register the app from protal using Microsoft account
user1 is in tenant1
add user1 as the external users to tenant2
request the access_token/refresh_token from tenant1(OK)
try to refresh the token using tenant1 in the request(OK)
try to refresh the token using tenant2 in the request(same error message)