How to solve "NoPermissionsInAccessToken" returned by Microsoft Graph when reading calendar or sending mail - azure-active-directory

Within our department we have a Classic ASP website that has been using our corporate Google accounts for authentication and to insert events into our Google Calendars. The organisation has just switched from Google to Office 365 and I'm trying to switch the code to use Outlook instead - with no success.
I can use the access token to GET https://graph.microsoft.com/v1.0/me and see the basic profile, but if I try to read calendar events or send an e-mail I see the message:
"error": {
"code": "NoPermissionsInAccessToken",
"message": "The token contains no permissions, or permissions can not be understood."
I created an Azure account with my personal Microsoft account and added an application. I added my colleagues and my corporate account as guest users. I set the permissions required and did the admin consent thing:
I then followed the steps on this page.
I first visit https://login.microsoftonline.com/{tenant id}/oauth2/v2.0/authorize, including the following query items:
client_id={client id}
response_type=code
redirect_uri={our URL}
response_mode=query
scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
state={number}
This returns a "code", which I send to https://login.microsoftonline.com/{tenant id}/oauth2/v2.0/token, including:
grant_type=authorization_code
client_secret={client secret}
client_id={client id}
scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
state={same number as above}
redirect_uri={same URL as above}
code={code returned from /authorize}
This returns the id, access and refresh tokens. If I decode the access token using https://jwt.ms/, it seems to contain the appropriate audience and scope:
"aud": "https://graph.microsoft.com"
"scp": "Calendars.ReadWrite email Mail.Send openid profile User.Read"
...although I notice that there is no "roles" entry, which I see in some of the documentation. Is that an issue?
I then send the access token to https://graph.microsoft.com/v1.0/me with the following headers:
"Authorization", "Bearer {access token}"
"Host", "graph.microsoft.com"
"Content-Type", "application/json"
"Prefer", "outlook.timezone Europe/London"
That will return my e-mail address, etc., but if I change the URL to anything else, such as /me/photo/$value, /me/calendar/events, or try to send an e-mail I'm told that there are no permissions in the token.
I see that there are other similar questions, but they are mostly for the client_credentials flow (I'm not sure that makes any difference), and none of the answers has helped me resolve my problem.
Can someone please let me know if I've obviously missed anything - or I'm going about this in the wrong way to access Graph data on the client side? It seemed so straightforward with Google, but I'm finding the Microsoft documentation and examples a bit less detailed.

Adding guest users is meaningless.
What you have done is Admin consent for the Azure AD with your personal Microsoft account.
What you actually need to do is Admin consent for the target Azure AD/ O365 tenant.
Construct a consent link as following:
https://login.windows.net/{tenant ID of the target Azure AD}/oauth2/authorize?response_type=id_token&client_id={client ID}&redirect_uri={reply url}&response_mode=form_post&nonce=a4014117-28aa-47ec-abfb-f377be1d3cf5&resource=https://graph.microsoft.com&prompt=admin_consent
Access it in a browser and log in with an admin account of target Azure AD.
Another issue is that you are using Get access on behalf of a user. So you have to assign Delegated permissions rather than Application permissions in the Azure AD app.

Related

How to get data from Microsoft Bing Ads API

I'm trying to get Bing ads spends from my firm. According to the Microsoft documentation, I understood that it's mandatory to use Microsoft Azure portal, get developer_token, client_id, tenant_id, client_secret, and access/refresh token to download the csv files with the data I want.
So, this is what I did:
I've received an invitation from my firm to Microsoft advertising onto this email adress:
abc#myfirm.fr, and I've generated my developer token.
With this email address, I've created a web application onto Microsoft Azure portal, which allow all king of users. Getting client_id, tenant_id, and generated a client_secret.
The redirect URL that I have chosen is http://localhost (according to the documentation but not sure this is the good URL to choose).
With Postman, I have tried with this endpoint:
https://login.microsoftonline.com/common/oauth2/v2.0/authorize
and the params (previously obtained) needed for the OAuth 2.0 authentication to get my access token. Without success.
The issue is here.
When I request the access token, a new browser window opens, and asks for an email address on which to authenticate. I'm using my email address abc#myfirm.fr and I received authentication completed onto Postman but into the response body I have access_token: invalid.
The role of my account is super admin.
So I'm trying to authenticate with a professional Microsoft Azure Account and this time I received into the browser Invalid redirect url.
I have also tried to start all over again with different email address, like my personal email address, or with the email address of the creator of the Microsoft Advertising account, and I get the error contact your system Admin into the browser.
I have also tried with the Python SDK project given in the documentation, with the error message.
I must have forgotten or misunderstood something.
Should we use the same email address (or same account) on Microsoft Advertising, on Microsoft Azure, and when obtaining the access token?
Do you have to pay and take an Azure subscription? (Already done but without success)
Thanks in advance, sorry for my English.
EDIT:
Thank for ypur reply. The full request is: https://login.microsoftonline.com/common/oauth2/v2.0/authorize with the following params:
-type: OAuth 2.0
-Header Prefix: Bearer
-Grant Type: Authorization Code
-Callback URL: https://localhost
-Auth URL: https://login.microsoftonline.com/{my-tenant_id}/oauth2/v2.0/authorize
-Access Token URL: https://login.microsoftonline.com/{my-tenant_id}/oauth2/v2.0/token
-my client id
-my client secret
-scope: https://ads.microsoft.com/ads.manage OR also testing with https://graph.microsoft.com/User.Read
-State: None
-Client authentication: send client credentials in body
Give me an access_token but when I click on use token and send the request, I'm not getting an refresh token
Once a user provides consent, you can get an access token and act on behalf of the user.
So when the browser session starts, you should enter your Microsoft Advertising credentials.
Remember to set scope=https://ads.microsoft.com/ads.manage in the request for acquiring the authorization code.
If you prefer to automate this process, you can refer to this script and steps to obtain an access token.

Create Microsoft teams meeting through API

In Azure Active Directory I've registered a new app and given it the Read and create online meetings permissions. I've granted admin consent for the permission and now I'm trying to create a meeting through the command line.
I generated a client secret for the app.
Then I'm requesting a access token using my tenant GUID, client ID of the app and client secret I generated. This gives me back a jwt. When I decode the JWT amongst the roles I can see "OnlineMeetings.ReadWrite.All" which gives me hope that I can actually create meetings using this bearer token.
I then send a POST request to https://graph.microsoft.com/v1.0/users/<my-user-guid>/onlineMeetings
with the following body:
{
"startDateTime":"2021-03-16T14:33:30.8546353-07:00",
"endDateTime":"2021-03-16T15:03:30.8566356-07:00",
"subject":"Application Token Meeting",
"participants": {
"organizer": {
"identity": {
"user": {
"id": "<my-user-guid>"
}
}
}
}
}
and the response comes back with
"code": "Forbidden",
"message": "Application does not have permission to Create online meeting on behalf of this user.",
Am I missing something?
Edit:
As some of the comments have suggested I should create an application access policy. So I'm following the documentation which asks me to Connect using admin credentials
When i run Connect-MicrosoftTeams -Credential $userCredential with my account it fails with the following error:
Connect-MicrosoftTeams: accessing_ws_metadata_exchange_failed: Accessing WS metadata exchange failed: Response status code does not indicate success: 406 (NotAcceptable).
Connect-MicrosoftTeams: accessing_ws_metadata_exchange_failed: Accessing WS metadata exchange failed
Connect-MicrosoftTeams: Response status code does not indicate success: 406 (NotAcceptable).
Connect-MicrosoftTeams: : Unknown error
But this is what is confusing me. I don't really know if I'm trying to login with the correct account. I'm using my personal account on azure which is (afaik) not a business account with skype for business.
I'm running the commands to log in on the azure portal's PowerShell interface. Am I supposed to run this on my local machine instead?
I think I'm not fully understanding what all of the moving parts are that need configuration.
Can I add those application Access Policies in the azure portal interface somewhere?
According to the api documentation, make sure you grant the OnlineMeetings.ReadWrite.All application permission to the application. Then you need to use the client credential flow to obtain an access token.
Please note that when you create an online meeting with an application token, administrators must create an application access policy and grant it to a user, authorizing the app configured in the policy to create an online meeting on behalf of that user (user ID specified in the request path).

Azure AD B2C. ROPC flow error The application associated with client id has no registered redirect URIs

The application associated with client id 09ac92da-a796-4cd9-973b-c97756____ has no registered redirect URIs
Description
I followed the steps described in https://learn.microsoft.com/en-us/azure/active-directory-b2c/configure-ropc?tabs=applications.
When attempting to obtain the token in Postman using ROPC I'm getting
{
"error": "invalid_request",
"error_description": "AADB2C90007: The application associated with client id '09ac92da-a796-4cd9-973b-c97756____' has no registered redirect URIs.\r\nCorrelation ID: e85003c3-cfd5-43ad-a74b-efa5c1ea6525\r\nTimestamp: 2019-12-06 19:47:42Z\r\n"
}
I should not be asked for a redirect URIs.
My POST is as follows:
URL: ''https://mytenant.b2clogin.com/mytenant.onmicrosoft.com/oauth2/v2.0/token?p=B2C_1_ROPC_Auth"
username: some_username_of_a_user
password: its-password
grant_type: password
scope: openid offline_access 09ac92da-a796-4cd9-973b-c97756____
client_id: 09ac92da-a796-4cd9-973b-c97756____
response-type: token id_token
I didn't reproduce your issue by following this document. Here are the main steps for your reference.
1.Create a resource owner user flow
2.Register an application(It is an application under Azure AD B2C, not Azure AD)
3.Test the user flow
This error generally occurs because you still need to configure some application claims in the b2c directory user flow to allow complete access to the application.
You need to make sure that the right versions of the authentication are in the reply url (likely extension v2.0) and that the reply URL is configured in the application and in the code.
Please look to the documentation for the reply URL schema that you would need to follow: https://learn.microsoft.com/en-us/azure/active-directory-b2c/tutorial-register-applications?tabs=applications#register-a-web-application
If you still run into this issue let me know and I can reach out to the correct product team contacts, as sometimes this can happen due to breaking changes on our end.

Azure client credentials grant oath not working in hybrid setup for Graph Mail API access

In hybrid setup if client credentials grant type is used to get token and if that token is used to get on-prem user messages (https://graph.microsoft.com/v1.0/users('onpremuser#onpremdomain.com')/messages/) using graph api it fails by providing UnknownError.
When debugged on IIS logs error shown was "This token profile 'V1S2SAppOnly' is not applicable for the current protocol." error_category="invalid_token".
However if authorization code grant or resource owner password credential (ROPC) grant if used to obtain token , we were able to get messages of on prem user using graph API.
Have attached screenshot of token for both. How to make client credentials grant work for on-prem user messages access using graph API (in hybrid setup) ?
Update
Update i went and edited web.config of rest in Exchange server to have V1S2SAppOnly in profiles. After that previous error is gone and new error is seen.
Bearer+client_id="00000002-0000-0ff1-ce00-000000000000",+trusted_issuers="00000001-0000-0000-c000-000000000000#ea6064aa-d6fc-48d3-abb8-1728e1f39e0b",+token_types="app_asserted_user_v1+service_asserted_app_v1",+error="invalid_token" 2000008;reason="The+token+should+have+valid+permissions+or+linked+account+associated+with+partner+application+'00000003-0000-0000-c000-000000000000'.";error_category="invalid_grant"
I think the problem is with the aud claim, i.e. the audience for token.
For the first token that you have shared
aud value is 00000002-0000-0000-c000-000000000000. This is the resource Id for Azure AD Graph API and not Microsoft Graph API. For Microsoft Graph API, you should be using https://graph.microsoft.com or Id 00000003-0000-0000-c000-000000000000
this token is probably the one where you used client credentials grant, as there isn't any user claim
For the second token that you have shared
aud value is https://graph.microsoft.com which is correct
this token is acquired in context of a user name anoop so I guess this is the one which is working for you.
What you want is:
Application with Client credentials => Graph API => Local Exchange.
This scenario isn't supported out-of-the-box, but you can however tell your local exchange server to accept those tokens. See this answer https://stackoverflow.com/a/56131954/639153
In a nutshell, you need to change the authentication config of your front-end exchange servers to accept client credentials from the graph api. By default only delegated credentials are supported, and these settings are not documented on the exchange side.
Warning, we tested these settings, and it's working but not supported by Microsoft
This is the blog where I've found the answer to your question. https://blog.thenetw.org/2019/05/13/using-client_credentials-with-microsoft-graph-in-hybrid-exchange-setup/

Calendar endpoint returns OrganizationFromTenantGuidNotFound

I'm currently trying to achieve in Node.js a direct login to Calendar/Users using Microsoft Graph.
What I've done so far are the following:
Login on the account and make sure that it currently has a calendar (the email is registered under #outlook.com).
Go to azure portal and create a new AAD name "Calendar Api" web API with return
URL http://localhost:3000
AAD -> App Registration -> Name: Test, reply url: localhost:3000, Required Permissions for Microsoft Graph (Users Read/Write, Calendars Read/Write), Windows AAD (offline_access), Grant Permissions, Generated a new secret key with no expiry date.
Went to Postman and started to generate a new token based on the following URL:
https://login.microsoftonline.com/{APP_ID_URI}.onmicrosoft.com/oauth2/v2.0/token
grant_type : client_credentials
client_id : {app_id}
client_secret : {app_secret}
scope : https://graph.microsoft.com/.default
And I a 200 OK with a token.
Upon inspecting the token:
"aud": "https://graph.microsoft.com",
"roles": [
"User.ReadWrite.All",
"Calendars.Read",
"Calendars.ReadWrite"
],
GET ON -> https://graph.microsoft.com/v1.0/users/ with Authorization Bearer and the above token will return a code status 200 along with the user account I've used in step 1.
GET ON -> https://graph.microsoft.com/v1.0/calendars/ with Authorization Bearer and the above token returns "Resource not found for the segment 'calendars'."
GET ON ->
https://graph.microsoft.com/v1.0/users/{user_id}/calendars OR /calendar OR /calendarView:
"code": "OrganizationFromTenantGuidNotFound",
"message": "The tenant for tenant guid '104fdcd9-76d1-4122-89a0-30cb00722de2' does not exist."
I don't really have a code because I am using POSTMAN to test the API first.
I would expect to get a list of events or a list of calendars instead of an error.
After some digging I found out what the problem was, so here is the full solution to this question.
You need a microsoft office 365 account with subscription, can get this by applying for one on office 365 develop.
Upon creating one, follow the instructions and add the apps to it.
Go to Azure Portal and log in with your office 365 account.
Create an app under AAD -> App registration
Follow step 4 and 5 of this question.
Try to access https://graph.microsoft.com/v1.0/users/{user_id}/calendars.

Resources