Category Archives: Angular

Allowing different Azure AD app registration permission sets for a single app (user and elevated admin consent) using the v1 auth model

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.

 

 

 

How to Inspect Dynamic HTML Elements (that keep disappearing!) in Chrome

I still find styling HTML elements difficult at times, trying to figure out where the styling is being inherited from and exactly which elements I need to apply styles to. The Developer Tools in Chrome go a long way to assisting with this. For this tip I’ll assume you are familiar with Chrome Developer Tools for inspecting HTML elements and CSS styles.

What I wanted to focus on was those frustrating elements that only exist on the page (in the Document Object Model) while a certain element has the “focus”. This often happens with navigation menu options or dropdown controls, where you have the menu options or dropdown options visible on the screen but as soon as you click something in Developer Tools (to go exploring), the menu options or dropdown options disappear and don’t exist on the page anymore! This is usually because an event such as the blur event is fired when you click outside the element and this removes the elements from the page that you are trying to inspect.

This tip might not work in all scenarios but it has gotten me out of trouble on a few occasions.

Here’s an example scenario. On the left side of the screenshots you can see the OnePlaceMail (Outlook Add-in) displayed in Chrome, on the right hand side is Developer Tools inspector window. I’m using a 3rd party control for my “Content Type” dropdown (it’s the Kendo UI for Angular library)

When collapsed it’s easy to inspect the kendo-dropdownlist element (that holds the selected value of ‘Document’. At this stage the menu options that will appear when I click on the dropdown don’t even exist in the DOM.

css-dynamic-inspection-chrome-cameron-dwyer-01-kendo-dropdown

When I do click to expand the dropdown, the image below shows that a new kendo-popup element appears in the DOM (and it contains sub-elements to represent each of the options). But the problem is if we now try to use the Developer Tools and expand that kendo-popup element to see those sub-elements then the dropdown collapses (because I’ve click off it) and the kendo-popup element is removed from the DOM and we’re left with nothing to inspect!

css-dynamic-inspection-chrome-cameron-dwyer-03-kendo-dropdown-expanded

So to work around this in the Developer Tools inspector, right click on the element that is driving the elements to appear/disappear (kendo-dropdownlist) and select Break on | subtree modifications.

css-dynamic-inspection-chrome-cameron-dwyer-06-break-on-subtree-modifications

Now go to the web page and click on the dropdown to show the dropdown options. They are shown (elements added to the DOM) but the Developer Tools inspector now goes into a paused state. The web page is effectively frozen.

css-dynamic-inspection-chrome-cameron-dwyer-07-break-on-subtree-modifications-paused

While in this paused state, you can now return to the elements tab and we can expand and explore that pesky kendo-popup element that was dynamically created. This time however the dropdown won’t collapse itself as we click around in the inspector.

css-dynamic-inspection-chrome-cameron-dwyer-08-break-on-subtree-modifications-paused-stays-expanded

I hope you find this tip useful

 

%d bloggers like this: