How do I get Graph API delta changes due to permissions changes? - sharepoint

I have an azure AD registered application. With delegated permissions of a user with AllSites.FullControl, I'm able to get drive/root/delta in Graph API.
Problems I'm having making the delta calls as the delegated user are:
the deltas are not consistent. Sometimes I get results back after changing the permissions of a file/folder, sometimes I don't
Despite that I'm passing in these Prefer headers deltashowsharingchanges, deltashowremovedasdeleted, deltatraversepermissiongaps, I'm not getting back #microsoft.graph.sharedChanged in the response.
The above issues are my primary questions.
Grasping at straws here, but please let me know if I would have better luck with an app-only authentication. If so, how to get it set up with my existing Azure AD registered application, without access to Powershell or Windows (e.g. if I need to use a certificate instead of client_id/client_secret, as there is conflicting information about this, and only instructions on how to get it done with Powershell). I've already started to try to test this, but have not successfully found information on how to get this working in a multi-tenant use-case, wherein I'm trying to access the Sharepoint of an outside tenant from an Azure AD registered app-only authenticated application. All existing instructions I've seen thus far are not multi-tenant and grant themselves permissions in their own Azure AD portal.

It turned out that indeed, using app-only client credentials authentication was necessary to get #microsoft.graph.sharedChanged in the response, though this is not documented anywhere. In addition, deltas are being returned consistently now. Presumably, Microsoft is doing something to try to return only deltas relevant to the delegated user, although that is not enough in my opinion to explain for the lack of deltas in some cases. Nevertheless, I'm getting the response I need using app-only client credentials.
Regarding use of certificate -- it was not necessary if accessing my own tenant where the app is registered, but if accessing a 3rd party tenant, a certificate was required instead of client_secret.

Related

Azure Identity SDK (JS) How to Authenticate to User's Azure Account

I am designing my first dev tool with the Azure SDK (JavaScript), and I am having a difficult time understanding how to authenticate users in production so the dev tool can access the user's Azure account. The tool is going to retrieve metrics from all of the user's Azure Functions in their tenant to display React component graphs based on those metrics over time. The app will be run locally with an npm run command.
My entry point for using Azure Identity in my app was this blog post (https://devblogs.microsoft.com/azure-sdk/authentication-and-the-azure-sdk/). I like the way the DefaultAzureCredential is working in development, using the tenant for whichever developer is running it by using the AzureCliCredential. I want a similar functionality for production, but for the browser instead of Azure Cli. In other words, if a user is already logged in to Azure Portal, it will get a credential for their tenant. How do I go about this?
One of the things I tried was opting into the Interactive Browser of the DefaultAzureCredential as described in that blog post. But even though, I could see the browser method in the src (https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/src/credentials/defaultAzureCredential.browser.ts), I couldn't figure how to opt into this when using the actual SDK. I couldn't find that method in the npm package in Azure Identity, and the documentation (https://learn.microsoft.com/en-us/javascript/api/#azure/identity/defaultazurecredentialoptions?view=azure-node-latest) didn't help me either. If this is the correct option for my use case, I would like to understand how to opt into it and use it.
Another thing I tried was implementing the InteractiveBrowserCredential. As long as I pass in a redirectUri with a port not already being used by my app, it did open another tab to tell me to login to the Azure Portal if I am not already logged in. This is exactly the user experience I would want in my app. However, after logging in the credential didn't actually do anything. The credential returned actually has a client Id equal to the application Id (04b07795-8ddb-461a-bbee-02f9e1bf7b46) of Azure CLI (https://learn.microsoft.com/en-us/troubleshoot/azure/active-directory/verify-first-party-apps-sign-in) for some reason. This led me to look into the Interactive Browser Credential and find out that it is using the Authorization Code Flow (https://learn.microsoft.com/en-us/javascript/api/#azure/identity/interactivebrowsercredential?view=azure-node-latest). This flow doesn't seem right for my use case, since I have to register my app. I am not trying to grant users access to my app, but access to their own Azure account. Is InteractiveBrowserCredential what I should be using?
Next, I looked into all of the different authentication flows. None of them seem quite right for my use case though. The closest one I found was the client credentials flow (https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow) since I am authenticating the user to their own Azure account and not my app. However, even this one doesn't seem quite right because when I looked up how to implement that flow with Azure Identity (https://github.com/Azure/azure-sdk-for-js/blob/main/documentation/using-azure-identity.md#clientsecretcredential-and-clientcertificatecredential) I found out that I have to pass in the tenant Id. But the app won't know the user's tenant Id of the user before they log in. Which flow is right for this use case?
It seems like there is a gap in my understanding. How can I use the Azure SDK to implement an authentication flow that authenticates the user to their own Azure tenant (not authenticates them to my app) through the browser?
Thank you ShwetaMathur for answering this question in Q & A. Posting the same here to help Stack Overflow community members.
To access your application by Azure AD users, your application should also need to register in Azure AD.
Once your application is register, you can acquire the access token based on different OAuth flows which is needed to call various resources(Users in your case) or protected API based on your scenario.
Azure Identity TokenCredential provide various flows to obtain an access token based on different scenarios.
InteractiveBrowserCredential is one way to launches the system default browser to interactively authenticate a user and obtain an access token.
Using access token, you can retrieve user’s info or access any other resource in Azure tenant. The InteractiveBrowserCredential uses Authorization Code Flow to authenticate users for browser based applications and to access resources further.
Client credential flow is OAuth flow commonly used for server-to-server interactions that usually run in the background, without immediate interaction with a user and help to acquire the token and call protected web APIs.
Complete reference

Microsoft GRAPH API possible without Azure App Registration?

I would like to try out Microsoft GRAPH API. But as far as I can tell there is no way to test it without App Registration client and tenant id in the Azure Portal. Is this correct? I don't have access to App Registration on Azure so if this is correct then I need to contact admin, which means I need to start a whole long-winded process.
No, this is not possible, to access the graph api, (for a work or student account) there must be an app registration to give you permissions to those endpoints.
It is possible IFF you are just trying to do CRUD operations and other GET requests that doesn't require an admin consent.
You can check the same inside Graph Explorer, for the requests that require your/admin's consent.
You must also consider that the access token gets refreshed when you try to integrate it with any code.
The accepted answer is misleading. This is possible using the Microsoft Graph PowerShell SDK.

Azure AD/Microsoft Graph API authentication implementation on web application

I wanted to implement o365 authentication in my current project. my intention is to standardize/centralize the login of employee and the administrative staff of the portal using Microsoft O365 authentication.
I managed to test out some of the sample projects online and it seems a bit confusing cause there are different ways of authenticating.
My ideal implementation is something as the drawing below.
On the API gateway for employee front end portal, I wanted to implement a gateway to verify the Microsoft access_token passed and obtain the (sid / object_id) to cross check with my employee database for function access.
As for the Administrator front end portal, it will be responsible for sync-ing the users front Azure AD daily automatically or the admin trigger the sync manually.
What confuses me was there are several ways to obtain the access_token, some tokens managed to return the info i wanted but I'm not entirely sure if that is the correct implementation.
For the case of verifying and sync-ing users from azure AD, both accepting different access_token in order to get the data/information.
Anyone expert here mind to guide me to the correct path of implementing the design above if not correct the implementation ?

Requesting Azure AD permissions on-demand

We have a multi-tenant single page app (and backend) that uses Azure AD for authenticating users. We'd like do queries to customer's Azure AD for retrieving groups but make it an opt-in behavior for customers (tenants). The reasoning behind that is that not all customers necessary need the functionality and would rather not grant us access to their AAD unnecessarily.
Is there some way of implementing this with Azure AD?
I've been trying to test with different OAuth /authorize calls with resource IDs and scopes but mostly I end up with "AADSTS65001: The user or administrator has not consented to use the application with ID ''. Send an interactive authorization request for this user and resource." error. Configuring the web app or backend to require the permission would surely fix the error but that will also make the approval of it mandatory for all users of the app.
Is there a way of using the authorize/consent API to request access to a new application on-demand?
An ugly work-around that should work would be to have 2 client IDs and 2 backend IDs with different permissions but ADAL.js doesn't seem to be designed to work with multiple Client IDs (it's singleton, for starters). Also Application Permissions should of course work but I'm not sure how much of those are required to search for groups.
Is there a way of using the authorize/consent API to request access to
a new application on-demand?
Do take a look at Azure AD v2.0. With their incremental & dynamic consent model, it is possible to do so though I am not sure if this specific functionality (managing groups) is available there.
I had a discussion with Azure AD team member recently about this (as we are also facing the same problem) and he suggested that we take a look at this.
Essentially the way things work in Azure AD v2.0 is that you start with basic set of permissions (like sign in, read profile etc.). Then when some tenant need specific permission, you essentially ask them to grant those permissions to your application at that time only. What this means is that different users in your application have granted different permissions to your application.
If you are using MSAL, and looking for a way to dynamically change your scopes before authenticating, have a look at this: https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-angular/docs/v2-docs/configuration.md#msalguard---dynamic-auth-request
More here: https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-angular/docs/v2-docs/configuration.md#platformbrowserdynamic

Permission error accessing /.auth/refresh

I'm using Azure App Service with authentication using Google and Microsoft account.
I can access mysite/.auth/me, without an issue upon login in.
But to refresh token, /.auth/refresh is returning me following exception.
You do not have permission to view this directory or page.
Not sure what access to be granted here in Azure blade.
The error message is actually a bit misleading. It's not that you don't have permission to access the API, but rather there are probably no refresh tokens in your token store. The way to acquire refresh tokens during user login is a little different for each provider. More details here:
https://cgillum.tech/2016/03/07/app-service-token-store/
In order for this to work, the token store must contain refresh tokens for your provider. If you’re not familiar with how to do this, here are some hints:
Google: Append an "access_type=offline" query string parameter to your /.auth/login API call (if using the Mobile Apps SDK, you can add this to one of the LogicAsync overloads).
Microsoft Account: Select the wl.offline_access scope in the Azure management portal.
Azure AD: This is a little complex right now, but take a look at my next post on enabling Graph API access. Follow the setup steps and this will also enable you to get refresh tokens for Azure AD (you can omit the Read directory data and the resource=… parts if they don’t apply to you). The plan is to simplify this in the future.

Resources