Azure Graph API - unauthorized after consenting app - azure-active-directory

I am trying to call graph api URL https://graph.microsoft.com/v1.0/me from a native application but get access denied.
If I call web api authorized controller from the native app, I successfully authenticate.
When I try to make a REST call in the backend, I also get access denied (providing user's token).
I have tried to implement it via HttpClient class (for the native app), and adal.js for the front-end - in both cases I successfully authenticate against the web api controllers decorated with Authorized attribute, but cannot call Graph API service.
I have run a web debugging proxy and ensured that the authorization header is sent properly.
I have done the following:
Created Azure Native App
Created Azure Web App
Provided permissions of the native app to the web api app
a. Added Read Directory Data permissions to the default permissions
Entered redirect URI in the Native app - same URL as the one of the Web API
Updated the Web app manifest from Azure AD. Set oauth2AllowImplicitFlow to true
Provided permissions of the web app
Windows Azure Active Directory:
a. Application Permissions - Read Directory Data
b. Delegated Permissions: Access directory as signed-in user
c. Delegated Permissions: Read Directory Data
d. Delegated Permissions: Sign in and read user profile
Microsoft Graph:
a. Delegated Permissions: Sign users in
b. Delegated Permissions: Access Directory as signed in user
c. Delegated Permissions: Read Directory Data
d. Delegated Permissions: Read all users' full profiles
e. Delegated Permissions: Sign in and read user profile
f. Application Permissions: Read directory data
g. Application Permissions: Read all users' full profiles
Consented the native app successfully
Consented the web api app successfully

Related

How to authenticate to personal OneDrive with Graph REST API

I'm trying to write an R package to let users access the files in their OneDrive folders from R. The API is Microsoft Graph.
Everything is working fine with OneDrive for Business (which is basically SharePoint under the hood, as I understand it). However, I can't get it to work with personal OneDrive.
Custom app registration, consumers authorization endpoint
When I use an app registration under my own AAD tenant, I get the following error from the consumers AAD authorization endpoint:
AADSTS50020: User account 'xxxxx#gmail.com' from identity provider 'live.com' does not exist in tenant 'Consumers' and cannot access the application 'd44a05d5-c6a5-4bbb-82d2-443123722380'(AzureRtest_cli) in that tenant. The account needs to be added as an external user in the tenant first. Sign out and sign in again with a different Azure Active Directory user account.
Custom app registration, 9188040d-6c67-4c5b-b112-36a304b66dad endpoint
From this page it appears that the token should be for the tenant 9188040d-6c67-4c5b-b112-36a304b66dad instead of the generic consumers. When I tried that, I obtained a seemingly valid token. However, talking to the https://api.onedrive.com/v1.0/drive endpoint results in a cryptic 401 error.
Azure CLI app registration, consumers endpoint
As a hack, I tried piggybacking off the Azure CLI's app registration. This fails with
AADSTS65002: Consent between first party application '04b07795-8ddb-461a-bbee-02f9e1bf7b46' and first party resource '00000003-0000-0000-c000-000000000000' must be configured via preauthorization. Visit https://identitydocs.azurewebsites.net/static/aad/preauthorization.html for details
Azure CLI app registration, 9188040d-6c67-4c5b-b112-36a304b66dad endpoint
Finally, I tried using the CLI app registration with this tenant, which also failed:
unauthorized_client: The client does not exist or is not enabled for consumers. If you are the application developer, configure a new application through the App Registrations in the Azure Portal at https://go.microsoft.com/fwlink/?linkid=2083908.
What are the exact steps I need to do to get to my personal OneDrive?
It turns out I had a bug in my code: I was using the tenant consumers.onmicrosoft.com instead of consumers. The process to communicate with Graph for personal OneDrive that worked for me was:
Use the authorization code flow as described here, with the following specs:
tenant: consumers
client id: for my custom app registration
scope: https://graph.microsoft.com/{scope} offline_access openid where the scope is one of those listed here
Use the API endpoint https://graph.microsoft.com/v1.0.
With regard to that last point, note that the documentation here is incorrect or at least outdated, as it still gives https://api.onedrive.com/v1.0 as the endpoint for personal OneDrive requests.

How to access Azure Maps API from browser using Azure App Service Active Directory authentication?

I have an Azure App Service with Azure Active Directory Authentication enabled. So the users have been authenticated by AD. How do I use that authentication to call Azure Maps from the JavaScript in the browser?
I was able to make calls from the browser to the maps API using the maps shared key, but I obviously don't want to do that. I was also able to have the browser call my server, and have my server use the shared key to call the maps API, but I don't want my server to have to be the middle-man for every call.
Well, in your case, you can hit https://webappname.azurewebsites.net/.auth/me to get the token to call Azure Maps API, please follow the steps below.
1.Navigate to the resource explorer -> find your app service-> add ["resource=https://atlas.microsoft.com"] to additionalLoginParams like below -> PUT.
2.Navigate to the Azure Active Directory in the portal -> App registrations -> find the AD App corresponding your app service -> API permissions -> add the permission user_impersonation of Azure Maps like below.
Note: If you could not find Azure Maps on the first page, just go to APIs my organization uses and search for ba1ea022-5807-41d5-bbeb-292c7e1cf5f6, then click it and add the permission above.
3.Then when the user login the web app, after he consents the permissions, you can get the token with endpoint https://webappname.azurewebsites.net/.auth/me, and use the token to call the Azure Maps API with javascript, in this way, the user just needs to login for one time, the token was generated via the azure ad auth.
Note: Before you getting the token, make sure the user logged in the app is already added as a role e.g. Azure Maps Data Contributor in the Azure Map Account -> Access Control (IAM), if not, follow this link to add it.

Unable to authenticate azure App service and get the data in spfx react solution

We are trying to call a web api hosted in azure app service from SPFX react webpart using aadhttpclientfactory.
We are receiving the below error.
Error: Error - Type : interaction_required - Description : AADSTS65001: The user or administrator has not consented to use the application with ID <> named 'SharePoint Online Client Extensibility Web Application Principal'. Send an interactive authorization request for this user and resource.
Please suggest the process to resolve the above issue.
Thanks in advance.
You need to consent to use the application. Go to azure portal->Azure Active Directory->App registrations->find your application->Api permissions->click Grant admin consent button(remember to login with the admin account)
If the permissions does't require admin consent, you can also use individual user consent which doesn't need admin permission.

Using same authentication for EWS API and Graph API

We've been using Azure Active Directory and EWS SOAP web services successfully.
Trying to see if we can use our current authentication method to be able to also invoke Microsoft Graph (i.e. https://graph.microsoft.com/v1.0/me/)
I went into Azure and added Microsoft Graph under App Registrations -> Settings -> Required Permissions.
This was our authorize endpoint url:
https://login.microsoftonline.com/common/oauth2/authorize?resource=https%3A%2F%2Foutlook.office365.com%2F
I changed it to :
https://login.microsoftonline.com/common/oauth2/authorize?resource=https%3A%2F%2Fgraph.microsoft.com
Is this all I had to do? When I try to go through the oAuth 2.0 flow, the authorize request seems successful, then I'm asked to enter my credentials, and then I get an error:
"Misconfigured application. This could be due to one of the
following: The client has not listed any permissions for 'Microsoft
Graph' in the requested permissions in the client's application
registration. Or, The admin has not consented in the tenant. Or, Check
the application identifier in the request to ensure it matches the
configured client application identifier. Please contact your admin to
fix the configuration or consent on behalf of the tenant. Client app
ID: b1313958-.... "
I went into Azure and added Microsoft Graph under App Registrations ->
Settings -> Required Permissions.
You mentioned this as part of your question. Please check if after performing these steps for your App Registration in Azure AD, did you click on the “Grant Permissions” button to provide consent or not.
Looking at the error it seems Consent for Microsoft Graph related permissions isn’t done yet.

How to enable multitenant authorization (AngularJS <-> Azure AD)?

How can I enable authentication with a multitenant AngularJS single page application calling a multitenant service Web API using Azure AD?
This is the high level flow I am trying to enable:
Multi-tenant AngularJS application [ClientApp] -> Multi-tenant ASP.NET Web API [ServicesApp]
I have a multi-tenant AngularJS application which requires Azure AD login using ADAL for JS (OpenID Connect). That web application is registered as a multi-tenant application ClientApp in a developer Azure AD, which I'll call DevAAD. I consented to use this ClientApp application in another Azure AD, which I'll call Tenant1. Once a user from the Tenant1 directory logs into the web application with their credentials into the login.microsoftonline.com portal, they are able to access the web UI. However, the UI is unable to call Web APIs on behalf of the user using the OAuth 2.0 Implicit Flow. This is the error message I am seeing in the Javascript code:
AADSTS65001: The user or administrator has not consented to use the
application with ID '<ClientApp_ClientID>'. Send an interactive
authorization request for this user and resource.
There is another Azure AD multi-tenant app representing backend Web API services called ServicesApp that is registered in the same DevAAD directory as the ClientApp UI application. The client ID and app ID URI of ServicesApp are the valid audiences for those services. This ServicesApp application has been consented to in the same Tenant1 directory. When invoked from a native client application with permissions to ServicesApp, the services are authorizing users from the Tenant1 directory using the OWIN middleware provided in System.IdentityModel.Tokens.Jwt 4.0.0 and the [System.Web.Http.Authorize] attribute in the controller.
Configuration details:
ClientApp
Azure AD application manifest has availableToOtherTenants set to true and oauth2AllowImplicitFlow set to true. ClientApp has permissions to access ServiceApp Azure AD application.
The AngularJS application has the following configuration:
adalAuthenticationServiceProvider.init(
{
tenant: 'common',
clientId: <ClientApp_ClientID>,
endpoints: { <ServiceEndpoint> : <ServiceApp_ClientID> }
}, $httpProvider);
ServiceApp
ValidateIssuer is set to false in TokenValidationParameters object in WindowsAzureActiveDirectoryBearerAuthenticationOptions configuration object passed to IAppBuilder.UseWindowsAzureActiveDirectoryBearerAuthentication()
"
knownClientApplications" property in "ServiceApp" Azure AD manifest is
set to ["<ClientApp_ClientID>"]
I have not been able to locate any examples of a multi-tenant web application calling multi-tenant Web APIs, specifically a single page application built with AngularJS. How can this be implemented with Azure AD?
You should try generating a Authorization Code URL using the template described here.
You can also copy this and replace the values with your own:
https://login.microsoftonline.com/common/oauth2/authorize?client_id=<appid>&response_type=code&redirect_uri=<replyurl>&resource=<resource>&prompt=admin_consent
Note at the end of the url I added the query string: "prompt=admin_consent".
This is something that only a company administrator can do, and it will consent to your app for the entire tenant, so that no one else needs to consent in the future. Note that you can change this to "prompt=consent" if you want to only consent at an individual user level, or remove it all together if you do not want to force a consent prompt.
Let me know if this helps!

Resources