In the SharePoint Framework v1.6.0 release, Microsoft introduced a new capability to the framework. After a long time in the developer preview state, that release gave developers the ability to call Azure AD secured APIs & endpoints through a proxy Azure AD application.
The way it works is that Microsoft has created a special Azure AD application in every SharePoint Online (SPO) tenant. A tenant admin grants this application permissions to a specific Azure AD secured endpoint. You then use the
AadHttpClient API to ask SPO to provide you with an OAuth access token to call the specified endpoint. SPO will authenticate and verify your SPO tenant has been granted this permission to the specified endpoint prior to returning the access token. You can then use this access token to directly call the target endpoint straight from your SPFx component.
You can learn more about this from the SPFx docs (Connect to APIs secured with Azure AD using the AadHttpClient) as well as from the recently released chapters in my course: Mastering the SharePoint Framework.
Make Sure you Understand How SPO Is Granted Permissions to the Endpoint
One very important aspect to this capability is that when you grant your SPO tenant permission to a specified endpoint, you are doing so for your entire tenant. I am being very specific in my wording there. In other words, once your tenant has been granted permission to a specified endpoint, any custom code can request an access token to call the endpoint.
The reason is simple: there's simply no way for the server-side code to determine what code triggered the request from the client for the access token. It can't tell it came from the console, a specific web part or a content editor web part.
In addition, permissions are not tied to any specific SPFx component. I can deploy & install a SPFx component that requires permissions without granting the permissions. In this case, when the component requests the access token, SPFx will throw an error. Furthermore, uninstalling the SPFx component will not remove any prior permission grants.
Another key point here: SPO permission grants are not associated with SPFx components: they are only associated with the SPO tenant.
Granting SPO permissions to the API
So how do you do you grant permissions to the special SPO Azure AD application? There are three options:
- declaratively request within an SPFx component & manually approve in the SharePoint Admin Center
- explicitly via PowerShell using the command line if you're on Windows
- explicitly via Office 365 CLI using the command line regardless of the platform you're on
The documentation page I mentioned above, Connect to APIs secured with Azure AD using the AadHttpClient, does a really good job explaining the different options and demonstrating each option.
Recommendation: Avoid the Declarative Option to Grant SPO Azure AD Permissions
Most of the demos you see use the declarative option that I mentioned above.
In this option, you specify the resource & permission your custom SPFx component needs in the component's package-solution.json file. When the component is deployed, the admin is displayed a message informing them they need to go approve the permission in the SharePoint Online Admin Center.
From here, the tenant admin can approve or reject the permission. This demos great, but there are a bunch of reasons why I don't like this:
Implies permission is tied to the SPFx component: When you look at the permission request, it shows the SPFx package that requested it. This sort of implies that this permission request is associated with the SPFx component. All it says is that this is the component that requested it… but it can be easily confused.
Makes the API admin list messy: Let's say you've already granted your SPO tenant the Mail.Read permission to the Microsoft Graph. If you deploy another application that has the same permission request, it will show up again as a pending permission request even though your SPO tenant has already been granted the permission. If you try to approve the permission, you'll see an error saying it's already approved… that's confusing!
What's even worse is that if you have multiple permissions requested in one SPFx package, they are all grouped together. So… let's say you had User.Read in addition to Mail.Read for the Microsoft Graph in the list of permissions. If one was already approved but the other wasn't, you would get another error… even though you're just trying to add one permission to the list.
What do you do now? You can reject or ignore the duplicate permission request because the existing approved request is all you need will serve the purpose, but that's not a great user experience from my point of view.
While the declarative options work just fine functionally, I am not a fan of it at all. From my POV the API management page in the SharePoint Admin center is broken or the design is flawed in how it works. If a permission is already granted to my tenant, granting it again should not throw an error or block me from granting other permission at the same time. But that's just my opinion.
For that reason, and the others I've outlined above, I recommend people avoid this option for granting their SPO tenant permissions to endpoints and services secured with Azure AD.
Recommendation: Grant SPO Azure AD Permissions with PowerShell or the Office 365 CLI
Instead, I recommend you use either PowerShell or the Office 365 CLI to grant your permissions. Which one is totally up to you… I prefer the Office 365 CLI, but it doesn't matter what you use.
With the command line option, you can list, request, grant and reject permissions. This can be done independently of the deployment of the component.
When I create an SPFx component that calls an Azure AD-secured API, I check for the HTTP status code 401 which tells me I'm not authorized to call the endpoint. When I see it, my web part displays a message showing the PowerShell / Office 365 CLI command to execute to grant the permission. Anyone can see it, but only a tenant admin can execute it.
This is just my opinion so take it for what it's worth, but I do encourage you to consider it and evaluate the experience when you are using this powerful capability in SPFx.comments powered by Disqus