I'm trying to access the SharePoint [Online] REST API from an external application. I've registered it in Azure under an admin account and assigned it the appropriate user-delegated permissions (Office 365 SharePoint Online).
I use ADAL.js to make a call to acquireToken and use that token in my Authorization header. A valid-looking token is getting attached, but I'm getting the following 401 error in the response:
Exception of type 'Microsoft.IdentityModel.Tokens.AudienceUriValidationFailedException' was thrown
The acquireToken() method does take a resource param, and from what I've read online, this value for the SharePoint API should be https://[tenant].sharepoint.com, but that only returns a null bearer token.
What I do instead (which triggers the previous 401 error) is to simply set the resource to the app ID generated in Azure. That ends up getting set as a token in my localStorage cache. So that bearer token does return, but I get the exception.
Two questions:
What is the resource string, and what is the proper value to call on acquireToken(), seeing that calling it with my app ID (same thing I'm using as the client ID in my ADAL config) is the only value which returns a bearer token successfully? Is there a list of proper resource strings for each Microsoft API? I've been having trouble finding documentation on this topic.
Is the problem with my configuration on Azure?
Thanks!
To use the SharePoint online REST, we can use the discovery service REST to find the SharePoint service endpoint. You can find all the service resource id from the serviceResourceId of response.
You can also consider using the Microsoft Graph which exposes multiple APIs from Office 365 and other Microsoft cloud services through a single endpoint.
More detail about discovery service REST API, you can refer here.
Related
Have tried many ways via code and Postman and no luck of getting a state of subscription like you would get via this link: https://learn.microsoft.com/en-us/rest/api/resources/subscriptions/list - here via the site you get a list of subscriptions and their "state": "Enabled" as an example.
Have no problem of getting auth tokens using scopes below but then impossible to get subscriptions list. If I use token from Microsoft site, the call in Postman to get subscriptions works fine.
The site is using Azure Active Directory OAuth2:
Type: oauth2
Flow: implicit
Authorization URL: https://login.microsoftonline.com/common/oauth2/authorize
Using Postman I have tried getting subscriptions using these scopes along with auth token:
api://blah/.default - Invalid Authentication Token Audience
https://graph.microsoft.com/.default - Authentication failed
https://management.azure.com/.default - pass but 0 results
https://management.core.windows.net/.default - pass but 0 results
I guess when using the site you login as a user and password vs in the code using client app and app secret. Is this workflow even possible?
The registered app has all kinds of API permissions. Something this simple should not be so hard. The idea here is to programmatically check via console app if Subscription is "Enabled".
After debugging this via Postman it turns out to be a permissions issue where you have to add the application you created/using to authenticate to the Access Control (IAM) of the subscription. This post describes the error and resolution: The client with object id does not have authorization to perform action 'Microsoft.DataFactory/datafactories/datapipelines/read' over scope
If you have multiple capacities created then you have to add your application to all of those subscriptions. Then you will get a list and can then check each one.
I have had been struggling to make my Azure Active Directory Oauth 2.0 Client Credentials Flow work with API Management. but I get authenticated via postman too. But in return I do not get any access token just a bunch of HTML. How can I fix this? The settings of the applications are exactly as per the documents including the validation of JWT Policy.
Basically I want my client apps to connect with my azure API's using Oauth 2.o without any consent using provided client id/secret. I'm trying to set this up for now with ECHO API provided out of the box with API Management console.
thanks
Postman Access token Error Screen
To use application permissions with your own API (as opposed to Microsoft Graph), you must first expose the API by defining scopes in the API's app registration in the Azure portal. Then, configure access to the API by selecting those permissions in your client application's app registration. If you haven't exposed any scopes in your API's app registration, you won't be able to specify application permissions to that API in your client application's app registration in the Azure portal.
For an example, if I sent scope parameter with custom name like https://testwebapp.in/.default without configuring same as application ID URI in Azure AD then is an expected behavior and you will get error AADSTS500011.
scope parameter in the request should be the resource identifier (application ID URI) of the resource you want, affixed with the .default suffix. For the Microsoft Graph example, the value is https://graph.microsoft.com/.default. This value tells the Microsoft identity platform that of all the direct application permissions you have configured for your app, the endpoint should issue a token for the ones associated with the resource you want to use.
Reference: https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow#application-permissions
The Setup :
Am trying to access Azure PowerBI based APIs using console application since my company wants to Suspend/Resume PBI capacity to optimize costing.
Have been successful in accessing those apis as per official documentation API Emulator Window, it works by perfect as it just asks with a authentication window for username and password of my outlook account and it generates authentication token implicitly successful.
When i tried to implement calling api from my console application which will be triggered automatically scheduled, there are ways to generate authentication token programmatically. Following are the methods i used to generate the same before accessing the PBI APIs.
Approach #1 : Generating token by using Azure Active Directory Authentication Libraries..
This approach asks to add AAD authentication libraries via Nuget, upon adding the same and it goes unsuccessful as the method AcquireTokenAsync takes no parameters but tutorial specified 4 parameters to be feed into this method (function overloading missing?). So i couldnt generate token using this approach. Surely a library version problem but the official MS documentation didnt explain anything above versions available over same.
Approach #2: Authorize Active Directory without dialog box StackOverflow Question with marked as answer
This approach upon calling HTTPResponseMessage, it gets hung up without going next line or catch statement.
Approach #3: Trying to emulate token generation using POSTMAN and using the generated token on my console app to check accessibility.
This approach gives a successful token generation but when using the generated token in the console app, it says unauthorised token.
Doubt Part:
Have generated ClientID, ClientSecretID and TenantID in Azure using AppRegisteration but dont know how this gets associated with PowerBI Service in azure. Do Azure Active Directory comes in place betweeen PBIService and AppRegisteration? Based on generated AppRegisteration details have tried to access this authentication api (https://login.microsoftonline.com/tenantId/oauth2/token) to generate token. This is successfully generates a token but miserably getting failed with unauthorised access on PBI api.
Am i badly missing something? will be helpful on what wrong about this concept of accessing PBI based API getting authenticated via console app. Asusual PBI community sites didnt help much.
1. How to manage Azure Power BI Embedded capacity
If you want to manage Azure Power BI Embedded capacity with rest API, please refer to the following steps.
create a service principal and assign Azure RABC role to the sp(I use Azure CLI)
az login
#it will create a service principal and assign contributor role to the sp
az ad sp create-for-rbac -n "jonsp2"
Get Token
Post https://login.microsoftonline.com/tenantId/oauth2/token
Content-Type: application/x-www-form-urlencoded
grant_type =client_credentials
&client_id=<sp app id>
&client_secret=<sp app password>
&scope=https://management.azure.com/
Call Rest API
POST https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.PowerBIDedicated/capacities/{dedicatedCapacityName}/suspend?api-version=2017-10-01
Authorization: Bearer <token>
2. How to call Power BI rest api
If you want to call Power BI rest api, please refer to the document and the document.
The detailed steps are as below
Register Azure AD application in Azure portal
Configure API permissions
Test (I test in postman)
a. get access token
b. call API
Suspend/Resume PowerBI API is described over here:
https://learn.microsoft.com/en-us/rest/api/power-bi-embedded/capacities/suspend
https://learn.microsoft.com/en-us/rest/api/power-bi-embedded/capacities/resume
Did you read the whole Azure REST API Reference?
All steps needed to send an HTTP request are documented over here:
https://learn.microsoft.com/en-us/rest/api/azure/
I'm getting Your access token has expired. Please renew it before submitting the request. when I call https://graph.windows.net/myorganization/oauth2PermissionGrants?api-version=1.5 endpoint.
To prevent any stupid questions - Yes, I know that using Microsoft Graph is recommended instead of Azure AD Graph. I'm aware of it and I'm using it. But for my current case I need to request exactly Azure AD Graph.
Tests case:
I successfully login on https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=.... and get code in the response.
I successfully exchange code and get access_token on https://login.microsoftonline.com/common/oauth2/v2.0/token.
I successfully make requests to any Microsoft Graph endpoint (ie https://graph.microsoft.com/education/me/classes).
I call https://graph.windows.net/myorganization/oauth2PermissionGrants?api-version=1.5.
I get the error Authentication_ExpiredToken Your access token has expired. Please renew it before submitting the request.
I successfully make requests to any Microsoft Graph endpoint, so the access_token is valid.
Based on this article: https://learn.microsoft.com/azure/active-directory/develop/active-directory-appmodel-v2-overview, I can use this access token to access both Microsoft Graph API as well as Azure AD Graph API.
So, I'm using v2.0 which should work for those: https://learn.microsoft.com/azure/active-directory/develop/active-directory-protocols-oauth-code.
What I'm doing wrong?
Thank you!
A token used to call the Microsoft Graph cannot be used to call the Azure AD Graph API.
When you look at the access token from Azure AD, there is a parameter called aud which stands for "audience". This property tells the API receiving the token the valid audience for that token.
If I own an API, "WebAPI1", and I get a token where the audience is something else, like "WebAPI2", I should reject that token, and not give the client access to my APIs. The reasons for this behavior should be obvious, but it causes major security issues if this check does not occur.
The aud value for the Microsoft Graph is https://graph.microsoft.com/ while the aud for Azure AD Graph API is https://graph.windows.net/.
When requesting an access token, you need to specify which specific resource you want a token for using the scopes parameter. This and more information can be found here.
The solution here is to get a different access token for the different API, and your issues should be resolved.
Let me know if this helps!
Are access tokens returned from Microsoft's v2 authentication endpoint valid for accessing the Excel REST API?
I receive an access token when going through the OAuth flow, and can access OneDrive endpoints such as:
GET https://graph.microsoft.com/v1.0/me/drive
But if I try to access an Excel endpoint such as:
GET https://graph.microsoft.com/v1.0/me/drive/items/{id}/workbook/
... I get 404 ResourceNotFound error
Note that I've registered for my Client ID via the Microsoft app registration portal
The v2.0 endpoint could works well for this API when I test with the work account. And I also reproduced this issue when I use the personal account.