With Azure Active Directory Application Registrations there are two versions of authentication model available.
v1 – all the permission scopes that your app may require must be consented to by the user up front.
v2 – permission scopes can be asked for dynamically as your app is running, if the user hasn’t already consented to the required permission scope then they will be challenged for consent at that time
v2 is a far more flexible model as it allows users try out and/or start using your app without having to consent to everything your app could ever want to get access to. After getting comfortable using the app, as the users explore and use more specific and advanced features in your app, you can ask for further permissions. Even more advantageous, certain API calls require a tenant administrator to consent to the permission on behalf all users. With v2 auth model end users can use features of the app that they have authority to consent access to, and then if a admin consents to some of the admin only permissions then even more features could be lit up in your app.
Here’s a good rundown on the state of app registration and auth in a recent episode of the Microsoft Cloud Show and you can read about the difference between v1 and v2 auth in the official Microsoft docs.
The Problem
Not all backend service APIs support the v2 auth model, and you can’t mix and match v1 and v2 auth model. If one or more of the backend service APIs you require only supports v1, then your entire app (and access to all service APIs) will be done using v1. At the time of writing the Microsoft Graph supports v2 auth, but SharePoint only support v1 auth. There is a technique for taking an refresh token acquired using v2 auth and exchanging it for a SharePoint access token but this technique can only be used from a custom Web API, and not from a Single Page Application (SPA) as it’s not safe to expose a long lived refresh token in client side code (i.e. JavaScript running in the browser).
This means there’s situation where you are stuck with v1 auth for now. Under v1 auth if your app has at least one permission that requires admin consent, then ordinary users are not going to be able to simply start using your app on there own, we are back to the days of having to “go through IT” to have an admin approve the app before it can be used.
The Solution
Well, it’s not a silver bullet solution that is going to fix any scenario, but the technique I’ll discuss here allows you to define two sets of permissions for your app. One set of permissions that contains just the minimal set of permissions to get users started using your app (you wouldn’t want any permission that require admin consent here) – We’ll call this the User Permission Set, then a second set of permissions (that contains those tougher to get approval for permissions that require admin consent) – We’ll call this the Elevated Permission Set.
What we are aiming for is the app to run with just the restricted User Permission Set (so that anyone can quickly start using your app) but maybe not with all the features enabled, and then allow an administrator to optionally provide consent on behalf of all users which then allows the app to use the Elevated Permission set (for all users).
I’ll assume you have already been able to create an app that successfully authenticates and consents a user against a single permission set (here’s a good starting point with Azure authentication concepts if you aren’t to this stage yet)
Step 1 – Create an Application Registration per permission set
Create an application registration for both the User Permission set and the Elevated Permission set (this will be a superset of the User Permission set). These registrations should almost be identical (e.g. same Reply URLs), but they will have different Application IDs, and obviously different permissions to represent the different permission sets. We will call these the User App Reg and the Elevated App Reg.
Step 2 – Change the normal auth flow to try to acquire tokens using the Elevated App Reg first
Your normal auth flow would be to try to acquire an access token for the service endpoint specifying the App Reg Id. Now we have two possible App Reg Ids, so what we do is that we try to acquire the access token first using the Elevated App Reg Id. If you are able to get the token then you are away just like the normal app flow (in this case consent must have been granted by an admin previously). But here’s the trick, if you fail to get the token (and the reason returned is that you need to prompt for consent) then proceed with your standard flow to acquire the token this time using the User App Reg Id and prompting for user consent if required. This way the user is able to start using your app as they will have authority to consent to the User App Reg.
Step 3 – Track which App Reg Id is in use
Once this auth flow is complete, track in the state of your app which App Reg Id you successfully acquired the token for, as that token will only work with the App Reg Id used to acquire it. Example: if the call to acquire the token using the Elevated App Reg Id worked then all future calls should specify the Elevated App Reg Id.
Step 4 – Conditionally protect features that require the Elevated App Reg
Now you are tracking which App Reg is in use you will know when your app only has the restricted User Permission Set. You can use this to hide features or prevent them from being used.
Step 5 – Expose a way for administrators to provide admin consent
Somewhere in your app you can provide the ability (e.g. a button) for a an administrator to provide admin consent. This will just launch the prompt for admin consent login URL and (always use the Elevated App Reg Id for this). Now when a user tries to use the app (see step 1) the attempt to acquire the token using the Elevated App Reg Id should work since an administrator has provided the consent.
If you are feeling really awesome you could (in the same session of your app) go through your auth logic again without restarting the app the discard the tokens you will have acquired against the User App Reg and get new tokens now against the Elevated App Reg and light up those new feature of your app immediately.
Video example of an Outlook Add-in utilizing this technique to provide user and elevated permission sets within a single add-in and allowing an admin to dynamically provide consent enabling additional features.
Leave a Reply