SharePoint Access token has two different scope values for tenants - azure-active-directory

when I decode SharePoint access token for Tenant A and B it shows as below
for the tenant A
"scp": "AllSites.FullControl User.Read User.ReadBasic.All"
for the tenant B
"scp": ".1f7f4061-caa1-44c4-b29a-6d877e9a5211"
are there any possible reasons to this kind of result for different tenants where i am expecting Teanat A result.
my token request call is similar to this
{ "grant_type", "authorization_code" },
{ "client_id", azureConfig.ClientId },
{ "client_secret", azureConfig.ClientSecret },
{ "scope", "https://123435350365.sharepoint.com/.default"},
{ "redirect_uri","url" },
{ "code", code }

I tried to reproduce the same in my environment and got the scopes successfully in both tenants.
I used the below parameters for both the tenants and got the access token for SharePoint successfully:
After decoding the token, I got the scope for both tenants successfully like below:
Please check the scope you are giving for Tenant B and verify whether your tenant has access to SharePoint API or not.
After decoding the token for Tenant B please check the aud and iss claims are valid or not.
Please note that value for the SharePoint Online Tenant Id may vary for each Tenant.
Make sure if you are giving permissions for Microsoft Graph then change the scope to https://graph.microsoft.com/.default.
If still the issue persists, try to raise Azure Support Ticket.
You can refer the below links to get some pointer to resolve the issue:
azure - SharePoint online OAuth2 token invalid_scope - Stack Overflow
How to access SharePoint Online data using Postman - REST API and Bearer token

Related

Getting powerbi embed token 403 Forbidden

I'm trying to get an embed token for power bi embedded.
I'm using 'App owns data' embed scenario.
I first get the access token of Azure AD and use it as Bearer token when calling embed token
Here is my Postman request details:
https://api.powerbi.com/v1.0/myorg/groups/{groyupid}/dashboards/{dashboardid}/GenerateToken
Request body
{accessLevel:"View"}
In authorization section I added the access token.
I received a 403 Forbidden response.
Here how I get the access token
I noticed that there is also another url to get token : https://login.microsoftonline.com/common/oauth2/token
What is the difference between the one with tenant id in the url
Then permissions for the AAD PowerBI application
Update
Thanks for the help I get another 404 not found error now
{
"error": {
"code": "PowerBIEntityNotFound",
"pbi.error": {
"code": "PowerBIEntityNotFound",
"parameters": {},
"details": [],
"exceptionCulprit": 1
}
}
}
For information I have added permission in PBI admin portal to pbireportingGroup an Azure security group that I created. ( as mentionned in docs )
Then I added to this group the AAD as member
Is that what should I do ?
403 means that your access token doesn't have the required permissions.
And you need to add the master account and service principal as the owner of the group / workspace (it may take 15 minutes to take effect).
UPDATE:
Now that you are using client credential flow, you should set application permissions:
And the resource in the request body should be https://analysis.windows.net/powerbi/api/.
Besides, you need to add the service principal as the admin of this workspace in Azure AD. (enter the name of your Azure AD app, and it will recognize its client id)

Azure Graph API giving error "Auth token does not contain valid permissions or user does not have valid roles"

I have been trying to list Microsoft Security Scores, following official instructions provided here
but I keep getting an error:
Auth token does not contain valid permissions or user does not have valid roles.
Auth token is being requested once the user has loged in and provided the consent to my registered application. Application has all of the required permission as described in the official documents: SecurityActions.Read.All, Subscription.Read.All, User.Read.All
Currently I am trying this in React.jS however I have tried this process in Postman and Node as well but I am still stuck.
const accessToken = await this.userAgentApplication.acquireTokenSilent({
scopes: config.scopes
});
const securityScores = await getSecureScores(accessToken);
if(securityScores && securityScores.value){
this.setState({
securityScores: securityScores
});
}
and scopes array looks like this:
scopes: [
'Directory.Read.All',
'AccessReview.Read.All',
'offline_access',
'Organization.Read.All',
'Policy.Read.All',
'profile',
'SecurityActions.Read.All',
'Reports.Read.All',
'SecurityEvents.Read.All',
'User.Read',
'User.Read.All'
]
It's a known issue. This error occours when you are using Implicit grant flow.
There is not a wids field in the access token obtained through the implicit flow. Based on the document, it may not be present in tokens due to token length concerns.
There are two workarounds.
Once the response mode is changed to response_mode=form_post the id
token, and access token if requested, are sent as a POST request and
contain the wids claim which allows the Graph API security endpoints
to be used.
Do an OBO call to get a token for Graph, then call graph to learn
what they wids or roles are on the token. You can also do OBO to get
an id_token which should have those claims in it.
See a previous discussion here. And you need to pay attention to rayterrill's answer and hpsin's answer.

How to solve "NoPermissionsInAccessToken" returned by Microsoft Graph when reading calendar or sending mail

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.

"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

How to get Azure tenant name from graph.microsoft.com?

I need to discover user's tenant name, since the service endpoint, resourceId that I'll be using an Azure service that requires me to specify the tenant name:
service endpoint: https://[tenantnamme].api.crm.dynamics.com/...
resource Id: https://[tenantname].crm.dynamics.com
I was hoping Unified Microsoft Graph API can discover this for me. I looked at the documentation, the closest I can see is to use
graph.microsoft.com/v1.0/organization
which will give me back:
verifiedDomains : [
....
"name" : "contoso.onmicrosoft.com"
]
But, I'm not sure if this is the right approach. What if an org has multiple verified domains? Does verified domain name is the same as tenant name?
Update: This is my real scenario. I have a web app that allows user to authenticate to Azure AD via OAuth2. I have no problem obtaining refresh token and access token from OAuth interactions. However, in other to use other service, it requires [azure-ad-tenant-name] in their service end point. That's my question coming from.
I believe that you're on the right track with the graph.microsoft.com/v1.0/organization endpoint. You should be able to find the tenant name in the verifiedDomains list. The entry that should contain domain with the tenant name is the initial domain:
{
...
"isInitial": true,
"name": "contoso.onmicrosoft.com",
...
}
Same. When you create a AD, you will obtain a domain name and a tenant id without tenant name, they are both the unique identifier of a AD. Use Get-AzureRmTenant to get all tenantid and domains in your subscription.

Resources