Azure Active Directory Authorization Token Has Expired - azure-active-directory

We are working on a custom connector for Power Apps. This connector basically uses post, get, patch, delete methods of the Dynamics Rest API. For authentication, we are using AAD as mentioned.
We are writing swagger JSON and uploading the file to create/update the custom connector, after which we have to provide CRM URL, Client ID, and Client Secret.
Everything was working smoothly until the custom connector started throwing error that the authorization token has expired.
{
"status": 400,
"source": "https://unitedstates-002.token.azure-apim.net:443/tokens/unitedstates-002/-5Ftest-20final-5Fc8793734b9d234d8-5F1ae6317311eb737e/a6bf39bb183d4f89870ba39642194dbe/exchange",
"message": "Error from token exchange: Bad authorization token. The access token has expired."
}
This error went away after we recreated the custom connector using the same swagger JSON without any change.
How can we avoid this error without needing to recreate the connector every time? Is there anything we are missing regarding to AD Tokens?

You can set the token lifetimes as per the documentation.
Please see here for more information:
Configurable token lifetimes in Azure Active Directory
Edit: This is apparently being deprecated May 1, 2020, but you should call for a refresh token if the token you currently have has expired.

Related

Issue in generating token with scope in Microsoft AAD using react. (401 Unauthorized)

I am using react-aad-msal and msal packages for implementing authentication using azure active directory. I am able to get the access token but every time the token is validated as "Invalid token" by back-end(.net core). Server is throwing error below error.
System.UnauthorizedAccessException: Neither scope or roles claim was found in the bearer token.
I am able to access all web services by authenticating with response_type "code" in postman.
I have tried to decode the token in jwt.io. It is clearly the issue with scope. I am attaching the image of config file in react.
config
In the image, the blurred part in blue color is clientId from AAD app.
In above config, I have provided the scope, but after decoding the token I am not getting the scope field.
You cannot directly request /common, because it will not be able to respond to your scope or role because you can't find the tenant you want to request the token. You should add your tenant URI (domain.onmicrosoft.com) or tenant id when requesting .
https://login.microsoftonline.com/{your-tenant-uri-or-your-tenant-id}/oauth2/v2.0/token

Getting access tokens from Postman: Tokens issued for the 'Single-Page Application' client-type may only be redeemed via cross-origin requests

We recently made a switch from Implicit Grant Flow to Authorization Code Flow with PKCE for our application, and now we're having some trouble getting access tokens from Azure AD from Postman. The app is registered in Azure AD and we're basically using the Postman procedure described here: https://developer.mypurecloud.com/api/rest/postman/index.html#enable_authorization. Calling the https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize endpoint works ok, but it hits an error when calling https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token:
"Error: Cound not complete OAuth 2.0 token request: "AADSTS9002327: Tokens issued for the 'Single-Page Application' client-type may only be redeemed via cross-origin requests.\r\nTrace ID: 8253f622-3425-4d0a-817c-281f86097300\r\nCorrelation ID: 9d84460f-ec02-4ace-af03-14d948e3d4ad\r\nTimestamp: 2020-04-15 14:02:03Z"
This is the access token request:
How can we get access tokens from Azure AD using Postman with this authorization flow?
Apparently this is a problem as the documentation is confusing.
Over the Azure Active Directory App Registration. Make sure you add the redirect url over the "Mobile and desktop applications" category.
When you read the documentation looks like you need to add the Redirect URL under the Single Page Apps. It even shows confirmation message saying "Your Redirect URI is eligible for the Authorization Code Flow with PKCE." but is not true.
This error can occur when the "Origin" header is missing from the request (see: GitHub comment).
Try adding the header:
Origin: http://localhost
If you're experiencing this failure whilst trying to authenticate using Postman, ensure that you have a platform authentication for Web.
Go to Azure AD > App Registrations > {your app reg} > Authentication > Add a platform. Redirect URI should be https://oauth.pstmn.io/v1/callback when using the browser.
For me I was trying update the MSAL v1 implementation to v2 implementation where I got this issue. After doing migration from web to SPA in the Azure where it clearly takes about the same fixed my issues.
https://learn.microsoft.com/en-us/answers/questions/315313/azure-app-registration-causing-the-following-error.html
https://github.com/AzureAD/microsoft-authentication-library-for-js/tree/dev/lib/msal-browser#implicit-flow-vs-authorization-code-flow-with-pkce
To get an refresh_token you have to add "offline_access" to the scope.
The documentation of the response to the access token request says:
An OAuth 2.0 refresh token. The app can use this token acquire additional access tokens after the current access token expires. Refresh_tokens are long-lived, and can be used to retain access to resources for extended periods of time. For more detail on refreshing an access token, refer to the section below.
Note: Only provided if offline_access scope was requested.
Documentation
I was able to resolve this by doing the following:
Within the Azure Portal:
Navigate to the App Registration that you are using for your protected API.
Next, navigate to the Authentication blade within the Manage menu.
Within your Single-page application platform, add the following Redirect URI, https://oauth.pstmn.io/v1/callback.
Save these changes within the Azure Portal.
Next, within Postman's New Token Configuration:
Manually set the Callback URL to the same URI specified above (i.e. https://oauth.pstmn.io/v1/callback).
Once the above are done, clear your cookies from within Postman, and re-attempt retrieval of the token.
Follow these steps:
In your registered app, add platform for mobile and desktop application like below image:
Get your code which will be redirected to https://login.live.com/oauth20_desktop.srf?code=<code>.
If you are using Postman to get token so cross origin issue chances can be there. So try below php code to get token:
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"https://login.microsoftonline.com/{tenenat-id}/oauth2/v2.0/token");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,
"grant_type=authorization_code&code={auth-code}&client_id={client-id}&scope=https%3A%2F%2Fmanagement.azure.com%2F.default&redirect_uri=https://login.live.com/oauth20_desktop.srf");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$server_output = curl_exec($ch);
curl_close ($ch);
var_dump($server_output);
1.You should first get the code in the browser,Enter the following request information in the browser address bar:
2.Then enter the obtained code and other request information in postman, you will get the access token
3.Please check: https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow

"One or more scopes are not compatible with each other" error when retrieving access token for the

I have an app that integrated with Outlook, Calendar via the Azure AD REST API v.2. I have tried to use the incremental and dynamic scopes to "upgrade" the user's token so that the app can access OneDrive as well, (so the user could directly upload her email attachments in her cloud).
The authorization code retrieval redirects went well and the user is asked for the additional scope after login (files.readwrite). However, on step 2 when I try to obtain the access token I get the following error:
System.Exception: Acquire token by authorization code returned BadRequest:
{
"error": "invalid_scope",
"error_description": "AADSTS70011: The provided value for the input parameter 'scope' is not valid. One or more scopes in 'https://outlook.office.com/mail.readwrite https://outlook.office.com/mail.send https://outlook.office.com/contacts.readwrite https://outlook.office.com/calendars.readwrite https://outlook.office.com/people.read files.readwrite' are not compatible with each other.\\r\\nTrace ID: b02fa0bf-6e86-4156-81e8-294dbc851500\\r\\nCorrelation ID: 3697bd18-554c-47e6-81cc-de3c47780fc9\\r\\nTimestamp: 2018-02-01 15:26:10Z",
"error_codes": [
70011
],
"timestamp": "2018-02-01 15:26:10Z",
"trace_id": "b02fa0bf-6e86-4156-81e8-294dbc851500",
"correlation_id": "3697bd18-554c-47e6-81cc-de3c47780fc9"
}
Or this error:
System.Exception: Acquire token by authorization code returned BadRequest:
{
"error": "invalid_request",
"error_description": "AADSTS700022: The provided value for the input parameter scope is not valid because it contains more than one resource. The scope https://outlook.office.com/mail.readwrite https://outlook.office.com/mail.send https://outlook.office.com/contacts.readwrite https://outlook.office.com/calendars.readwrite https://outlook.office.com/people.read files.readwrite is not valid.\\r\\nTrace ID: 9781d206-11b3-46c8-b972-8c4e77641c00\\r\\nCorrelation ID: 7e63af89-6e95-45f4-abaa-8f32051fb9ef\\r\\nTimestamp: 2018-02-01 15:36:32Z",
"error_codes": [
700022
],
"timestamp": "2018-02-01 15:36:32Z",
"trace_id": "9781d206-11b3-46c8-b972-8c4e77641c00",
"correlation_id": "7e63af89-6e95-45f4-abaa-8f32051fb9ef"
}
I assume I can't use the same token for both Outlook and OneDrive access because they are "different resources", one being part of the Office 365 and the other in Microsoft graph, however, I struggle to find a comprehensive list of which resources are compatible with which in here (https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-scopes).
My question is, does this mean that I will need to maintain 2 different tokens (my app uses the offline scope to refresh the token) for OneDrive and Outlook?
Also is there a difference between OneDrive for a personal account and OneDrive for a business accounts (which I think is the same as Sharepoint)? When working with outlook I can use the same code for outlook.com and Office365 emails, but I am not sure this is the case when it comes to working with files.
With the Google APIs it's quite simple to just add the Google Drive (or any other API) scope to your Gmail access scopes, but I guess that's not the case with the Microsoft APIs.
Thanks
Yes you will need two tokens. As juunas said in his comment, the problem is the audience, or the aud parameter in the token. You're asking for scopes that apply to two different audiences: https://outlook.office.com and https://graph.microsoft.com.
The good news is that these two APIs do have overlapping scopes, and Azure AD will allow you to use a refresh token issued for Graph to get a token for the Outlook API. So here's what I suggest (assuming you're doing authorization code flow)
Do your authorization request using Graph scopes:
mail.readwrite
mail.send
contacts.readwrite
calendars.readwrite
people.read
files.readwrite
Do a token request with grant_type=authorization_code using those same Graph scopes. This gets your Graph token + refresh token.
Do a token request with grant_type=refresh_token using the refresh token from previous step, but this time with ONLY the Outlook-applicable scopes, qualified for https://outlook.office.com. This gets your Outlook token.
https://outlook.office.com/mail.readwrite
https://outlook.office.com/mail.send
https://outlook.office.com/contacts.readwrite
https://outlook.office.com/calendars.readwrite
https://outlook.office.com/people.read

Acquiring a token for graph.microsoft.com with adal.js

I've been using Azure Active Directory and adal.js to authorize web apps client side and it's worked great. Recently had a request to have user photo instead of a generic user icon.
I added Microsoft Graph permissions to the app registration. And tried to get a token for the user photo request like...
authContext.acquireToken('https://graph.microsoft.com', callback);
Which resulted in the response_type 'token' is not supported for the application error. So I found ADAL JS - response_type="token" is not supported suggesting setting "oauth2AllowImplicitFlow": true in the app manifest, which I did. Now I get Token renewal operation failed due to timeout error.
I've also added 'https://graph.microsoft.com': 'https://graph.microsoft.com' to the endpoints prop of the context config.
What do I have to do get this working? Way too much time spent just trying to get users' photos. Thanks.

Delete groups in Microsoft Graph API in C#

I get an authorization 401 error code when I try to delete a Group from the API in C# but if I try it in postman it succeeds. Feels kinda weird because I run the same command but it doesn't work...
The problem I think I have is that to DELETE a group in Office 365 I need to login to my account and that the application can't makes this action.
I gave all Group.ReadWrite.All access and all other permissions for the application. So I think I need to pass my Login credentials for Azure AD or am I incorrect.
Request :
StatusCode: 401,
ReasonPhrase: 'Unauthorized',
Version: 1.1,
Content: System.Net.Http.NoWriteNoSeekStreamContent,
Headers:
EDIT
I tried to not use my GetAccessToken() and use the token I got when using OAUTH 2.0 verification in Postman. If I took that bearer token I had no problem running my script and using DELETE.
So my question what the difference of using ADAL in C# code and the call that Postman Auth2.0. When using Postman I get a login page where I login to my Azure account, can I replicate this in code? For the authentication in C# I use this example.
NEW EDIT
As one wrote in the chat, I checked the access token and what roles I had on a website.
roles: [
"EduRoster.Read.All",
"Mail.ReadWrite",
"User.ReadWrite.All",
"Calendars.Read",
"People.Read.All",
"Group.Read.All",
"Directory.ReadWrite.All",
"MailboxSettings.Read",
"Contacts.ReadWrite",
"Group.ReadWrite.All",
"Notes.Read.All",
"Directory.Read.All",
"User.Read.All",
"Mail.Read",
"Calendars.ReadWrite",
"Mail.Send",
"MailboxSettings.ReadWrite",
"Contacts.Read",
"Member.Read.Hidden",
"Notes.ReadWrite.All"]
Some clarification: If you have a token and it doesn't have the necessary claims/permissions to make the API call you are trying, you'll should get a 403 Forbidden. If the token is missing in the API request or malformed, you'll get a 401 Unauthorized. Please see https://developer.microsoft.com/en-us/graph/docs/concepts/errors.
Are you making direct HTTP REST calls to Graph, or are you using the client library? I suggest that you look at some of our samples to get started for examples of token acquisition together with calls to Microsoft Graph. Try https://github.com/microsoftgraph/console-csharp-snippets-sample (uses a .Net client library) or https://github.com/microsoftgraph/aspnet-connect-rest-sample (uses direct HTTP REST calls).
Also are you acquiring a token in the context of a (signed-in) user, or in the context of the application (no signed in user)? If the former, you need to request a "delegated" permission. If the latter, you need to request an "application" permission. Please see these concepts: https://developer.microsoft.com/en-us/graph/docs/concepts/auth_v2_user and https://developer.microsoft.com/en-us/graph/docs/concepts/auth_v2_service
Hope this helps,
You're on the right track.
The Delete Group method support both Delegated (Authorization Code or Implicit OAUTH grants) and Application (Client Credentials OAUTH grant) models. Both Delegated and Application flows require the Group.ReadWrite.All scope.
The reason you're getting a 401 Unauthorized error is that your application hasn't received Admin Consent for the tenant you're connected too. When using Client Credentials there is no User to authenticate so before your application can interact with the tenant, an Admin must first explicitly authorize your application and the scopes you're requesting.
You can find a walk through at v2 Endpoint and Admin Consent.

Resources