Azure AD authentication to call Office 365 and Graph API REST - azure

I've created a sample MVC app using VS 2015 and used Azure AD Auth wizard. When I launch this web application, it asked me to register app with Azure AD (first time only) and then userid/password. I have entered Office 365/Azure AD account and successfully logged in. Everything is working perfectly fine and at the top right, I can see Hello "myname".
Now I tried to make REST call to Office 365 using RestSharp. It is giving me 403 error (access denied).
When I tried to use graph api url https://graph.windows.net/testname.com/groups?api-version=1.6, I am getting error unauthorized access.
Here is my test code with graph API call:
string url = "https://graph.windows.net/testname.com/groups?api-version=1.6";
var client = new RestClient(url);
client.ClearHandlers();
var jsonDeserializer = new JsonDeserializer();
client.AddHandler("application/json", jsonDeserializer);
var request = new RestRequest(Method.GET);
var queryResult = client.Execute(request);
I am using same code with O365 REST url for Office 365 call.
Why I am getting access denied in both cases if my app is already authenticated against Azure AD which is the base authentication. Also Request.IsAuthenticated is always true.
Isn't a single identity provider (AAD) used for Azure, Office 365 and related resources?

It's possible your app isn't configured to call the /groups endpoint of graph. While the end user is authenticated and you have gotten tokens for the Azure AD Graph (graph.windows.net), this access token needs to have a certain set of permissions to call the endpoints.
To configure these graph permissions, you can go to the Azure Portal, select Azure Active Directory, then App Registrations, and finally Required Permissions. The resource your calling is Windows Azure Active Directory and then you can look through the list of scopes for what you want to call.
Another great resource I'll recommend is the Azure AD Graph Explorer. This can help understand the type of data the graph can provide.
Edit: Checkout comments for answer. OP had used the OpenID Connect middleware (OWIN) and needed help getting an access token for a resource. In order to do this, you must use a combination of OWIN + ADAL. OWIN gets an auth code, and ADAL can exchange this auth code for an access token.

Related

Microsoft graph api - Tenant not recognized

I created an app in App Registrations service in Azure portal to access Microsoft 365 graph api's.
I could create token using https://login.microsoftonline.com/570fa6c*************************f233/oauth2/v2.0/token , but when i tried https://graph.microsoft.com/v1.0/reports/getTeamsUserActivityUserCounts(period='D7') using the token generated above, i am getting error - We do not recognize this tenant ID 570****************f233. Please double-check the tenant ID and try again
I have a free trial subscription
Could you please help, what am i missing here.
Thanks,
Neema
I tested in my environment and it is working fine for me please use the below steps so you do not missed anything.
Created an application in Azure AD and given Application -> Report.Read.All API permission.
Generated access token using postman with below Parameter passed in Body.
https://login.microsoftonline.com/tenantid/oauth2/v2.0/token
Add an assignment to above AzureAD application with Reports reader Administrative roles in Microsoft Teams.
Add Assignment->Select Member->Search you application and add it.
Now finally run the getTeamsUserActivityUserCounts API with Authorization Key Bearer {token}.
For me showing the blackOuput as I have no activity for any users.

Secure Azure Function API with MSAL

I have Azure Functions which i want to authenticate using access token.
I have following things set up
Azure App which is being used by Angular SPA to authenticate user
Access token which is used to invoke graph APIs, Permissions are set in Azure app (point 1)
Azure Function which is having http triggers (APIs) which are being used by SPA
Currently, APIs are anonymous and can be invoked from anywhere. i want to secure these apis using access token which is being used by graph api (point 2)
I think the best approach for me is AAD multi tenant authentication. However, When i click on "Authentication (classic)" it gives me This app is configured using the new authentication experience. Click here to access Authentication (preview).
Also, if i keep authenticated with following options, i get "You do not have permission to view this directory or page." error
Most of the articles which i find online are talking about AAD. for me that option is not enabled.
I have tried following articles to make it work but somehow its not happening. can anyone suggest. how can i achieve this.
https://medium.com/medialesson/protecting-azure-function-apps-with-azure-ad-authentication-authorization-fd167ce4fe33
https://medium.com/geekculture/easyauth-in-functions-app-with-azure-active-directory-29c01cad8477
is there something i need to do in my existing Azure app to make it work ?
Per my understanding, your Azure function is protected by AAD using Authentication(Easy auth). And now, your angular SPA would like to access this function. Pls follow the steps below:
Go to Azure AD => App registrations => The App you created to protect your Azure function=> Expose an API to add a scope, for instance, access_as_user so that your SPA could require an access token for this scope:
Got to Azure AD => App registrations => The App you created for your SPA app=> API permissions => Add a permission => My APIs to grant the scope we just created:
Click the grant admin consent button to finish the process.
In your SPA app, use MsalService to acquire an access token with scope: api://<your azure function app id>/access_as_user, by this token, you can access your Azure function. For a quick test, I just test it in post man and it works perfectly:
Not use this access token
Bring this access token
UPDATE
Basically, your app request diagram as below:
SPA (request with access token)==> Easy Auth of Azure function (valideate token,if pass,goes into Azure function code logic,if not, return 401)==> code logic of Azure function (obo flow to get access token for Graph API) ==> call Microsoft Graph API
By now, we have finished steps 1 and 2: get access token for easy auth and pass easy auth goes into Azure function code logic.
So in the Azure function code logic, we need to do 2 things:
Get the access token in the request header
Use the access token and OBO flow to exchange a new access token for Microsoft Graph API. Just refer to request below to use OBO flow to exchange an access token for Microsoft Graph API:
BTW, pls make sure that your Azure function app has been granted with permission user.read and Calendars.Read:
So that you can get a new access token to call Microsoft Graph API:
May be this will help someone, I have tried using above suggestions but could not achieve 😭 instead i am using Key for each Azure function. and storing those keys in azure Key/Vault and retrieving those keys within App settings of the application using managed identity. This may be not be the ideal situation but i think it will do for me at the moment. I really hope MS will improve their documentation some day along with sample code/steps

Azure Function with Azure AD Authentication - Allowed Token Audiences not work for Microsoft Graph

I have configured Azure Function with Azure AD auth, follow this doc - Enable Azure Active Directory in your App Service app.
After the configuration, it will add the function app url e.g. https://appname.azurewebsites.net to the Allowed Token Audiences like below automatically, then we can easily use the client credential flow to get the token to call the e.g. http trigger in my function app.
If I add the Azure AD Graph resource url https://graph.windows.net to the Allowed Token Audiences, I can also use this flow to get the token to call my function.
But if I add the Microsoft Graph resource url https://graph.microsoft.com and get the token to call the function, I will get the error.
You do not have permission to view this directory or page.
How to solve this issue? Is this correct usage of Allowed Token Audiences? If not, why the https://graph.windows.net work fine?
Any ideas are appreciated.
Can you please check in your app registration in azure AD under api permissions if Microsoft graph has been added ? If not please add it as a delegated permission and give it a try.
According to the document you need to provide Application ID URI in Allowed Token Audiences. Please refer to the document
If this is a cloud or server app and you want to allow authentication tokens from a web app, add the Application ID URI of the web app here. The configured Client ID is always implicitly considered to be an allowed audience.

How to create users using Microsoft Graph API (from Graph explorer and Java application)

I am new to Microsoft Graph API. I have read many articles on the web to understand the usage of Microosft Garph API for managing users in Azure AD. I am creating a Springboot based REST API service, which needs to create users in Azure AD.
I have registered my application in Azure Active Directory. I have also 'Directory.ReadWrite.All" permission for Microsoft Graph API. I wanted to first try to create the user from Microsoft Garph explorer. In the Graph Explorer, I have to give authorization token in the Request header. In order to create authorization token, I have followed the instruction given in the link https://learn.microsoft.com/en-us/graph/auth-v2-user. I have created the following URL based on the instruction, for obtaining Access token.
https://login.microsoftonline.com/{mytenantID}/oauth2/v2.0/authorize?client_id=validclientID&response_type=code&redirect_uri=https://localhost:4200&response_mode=query&scope=Directory.ReadWrite.All&state=12345
When the above URL is accessed from the web browser, I get a message which says "Need Admin Approval". I am not the admin of the Azure AD and I do not have access to the admin of my client, so I am really stuck. Can anybody help me understand whether I will have to get admin consent each time I need to access "create user" functionality of Azure AD through MS Graph API? . I would also also need the create user functionaltiy in the Springboot API. In this case, how would Admin Consent work?. Is there anyway that the create user functionality can work without Admin consent.
I have read the following two questions in SO before posting this question
How can I find the Admin Consent URL for an Azure AD App that requires Microsoft Graph "Read directory data" permission?
Create user using Microsoft Graph
if you just want to create a user in your tenant , you can follow the steps below :
Create a new Azure AD app in your tenant, ask your tenant admin to grant "Directory.ReadWrite.All" permission to this app :
Create a app secret for your Azure AD app :
Use this secret and this Azure AD app ID to get access_token to call Microsoft Graph API :
Request URL :
POST https://login.microsoftonline.com/<-your tenant name->/oauth2/v2.0/token
Request Header :
Content-Type: application/x-www-form-urlencoded
Request Body:
grant_type:client_credentials
client_id:your client Id
client_secret: Your application secret
scope=https://graph.microsoft.com/.default
You will get an access_token from this API calling.
See the screen shot below:
3. Using the access_token we just created to call Microsoft Graph API to create a user :
As you can see , a user has been created :
If you have any further concerns , pls feel free to let me know : )

Credentials prompt for access to Azure management APIs

I've been using the Azure fluent management APIs (https://github.com/Azure/azure-libraries-for-net) with some success in .NET Core.
However, I want to prompt the user to enter some credentials for a Microsoft account. Those credentials would have access to one or more Azure tenants / subscriptions, so I'd like to be able to use the result to browse and manage resources there.
This is something very close to what I would believe Azure Data Studio does: you can enter some Azure creds, and your resources will appear in the app.
I'm trying to understand the best approach for this. There seem to be a billion sites out there when you talk about Azure AD app registrations, but I haven't found a fruitful specific search query yet. I know I can register an app, get a client ID and client secret. I know I can set it to be usable by organisational accounts in the current tenant, or all tenants.
I can add the "Azure Service Management (delegated permissions : user_impersonation)" permission to my API permissions section for the app, but what's next?
If I use Microsoft.Identity.Client (as in https://learn.microsoft.com/en-us/azure/active-directory/develop/quickstart-v2-netcore-daemon), I run into some questions:
AcquireTokenForClientAsync doesn't prompt the user - I guess because it's getting a token for the app to act with its own permissions?
AcquireTokenOnBehalfOfAsync wants a JWT.. great! I'll pass the one I got from AcquireTokenForClientAsync! Nope, AADSTS70002: Error validating credentials. AADSTS500137: The token issuer doesn't match the api version: A version 1 token cannot be used with the v2 endpoint.
I don't know what scope I want. https://management.azure.com/user_impersonation is apparently invalid.. https://management.azure.com/.default works, but is that right? It's a guess, combo of the former and a .default suffix I found for Graph API scopes online. Any docs on this?
I ultimately get a JWT and tenant ID back. I can't find a way to use a JWT with the Fluent management APIs.. and my account (for instance) is associated with 3 tenants or 5 different tenants / directories - so how do I choose?
That's just what I've tried, the appropriate route might be a different one. In summary: I want a .NET Core Console app to request user credentials, and then get access to the Azure resources they have access to, in order to perform some resource management.
AcquireTokenForClientAsync doesn't prompt the user - I guess because it's getting a token for the app to act with its own permissions?
You are using the OAuth 2.0 client credentials grant to access web-hosted resources by using the identity of an application. This type of grant commonly is used for server-to-server interactions that must run in the background, without immediate interaction with a user .
AADSTS70002: Error validating credentials. AADSTS500137: The token issuer doesn't match the api version: A version 1 token cannot be used with the v2 endpoint.
Azure AD provide two service : Azure AD V1.0 and Azure AD V2.0 . Please refer to Comparing the Azure AD v2.0 endpoint with the v1.0 endpoint . You can't use v1 token to acquire v2's token in a on-behalf-of flow .
AcquireTokenOnBehalfOfAsync wants a JWT.. great! I'll pass the one I got from AcquireTokenForClientAsync
AS pointed above , That function is used to acquire an access token for this application (usually a Web API) from the authority configured in the application, in order to access another downstream protected Web API on behalf of a user using the OAuth 2.0 On-Behalf-Of flow. So you can't use app token which acquire using Client Credential flow .
https://management.azure.com/.default works, but is that right? It's a guess, combo of the former and a .default suffix I found for Graph API scopes online. Any docs on this?
You are using the Azure Active Directory v2.0 and the OAuth 2.0 client credentials flow , when sending a POST request to the /token v2.0 endpoint ,the scope should be :
The value passed for the scope parameter in this 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 informs the v2.0 endpoint that of all the direct application permissions you have configured for your app, it should issue a token for the ones associated with the resource you want to use.
Please check the Get a tokensection in above document .
I ultimately get a JWT and tenant ID back. I can't find a way to use a JWT with the Fluent management APIs..
AFAIK , currently Azure AD V2.0 apps can use:
Its own API
Microsoft Outlook APIs
Microsoft Graph API
Azure AD V2.0 currently doesn't support Azure management APIs .
So you problem is you need to allows work and school accounts from Azure AD and personal Microsoft accounts (MSA) which works with Azure AD V2.0 , but you can't use Azure management APIs . You can use Azure management APIs in Azure AD V1.0 but it allows only work and school accounts to sign in to your application , unless you invite Microsoft accounts as guest user in Azure AD V1.0 ,but you need to configure to point to the tenant-specific endpoint :https://login.microsoftonline.com/{TenantId_or_Name}). during authentication if you want to login with MSA in v1.0 apps.
Update:
You can use Code flow and azure ad v1.0 endpoint , user will be redirect to AAD's login page and enter their credential. Here is code sample for .net Core .
With Azure AD V1.0 endpoint , requests are sent to an endpoint that multiplexes across all Azure AD tenants: https://login.microsoftonline.com/common . When Azure AD receives a request on the /common endpoint, it signs the user in and, as a consequence, discovers which tenant the user is from. See document here . But in this scenerio ,you can only use work and school accounts(AAD) account to login .
The code sample in your link is using Azure Service Principal for Authentication , no interactive user login . You can use OpenID Connect Owin Middleware for authentication in .net Core applications as shown here .

Resources