7/24/16

AngularJS SPA Controller Claims Authorization

Overview
In a previous article, we discussed the use of directives to enable claims based authorization on the user interface elements. For some scenarios, we notice that a directive can have performance issues as it is called everytime is declared on the mark-up. For the cases where there is an ngRepeat, this can lead to many calls depending on the size of the collection.

With the auth directive implementation, we notice on the browser console the number of times the directive is called.  This lead us to explore other options with better performance, and that also can provide the same results. With that in mind, we now take a look a providing claims authorization with controller only implementation.
Security Service
This service has a simple implementation in which it checks if a particular claim already exists for the current user by managing the claims information as a property. This service is injected into the controller with the purpose to manage the validation of the claims for the user. The controller sets scope variables which can then be used on the view to enable some of the user interface behavior like hiding elements for which the user has no permissions.
spa-auth-controller.png

Controller Implementation
If we look at the mark-up for the delete and edit buttons, we notice that we could manage the visibility of those controls by using the ngShow native directive. In addition, we need to have some controller variables which can be watched by Angular to enable the behavior. We can now take a look at the implementation details with the following JSFiddle.

On the JavaScript tab, we can see our controller implementation.  We are creating a controller variable for each of the claims that we need to validate (claimMapping). To figure out the if the claim is available, we pass the claims tags to the $svcAuth service which verifies if the claims  exists by calling hasClaim.  
The state of each variable is set by calling claimResuts. If the claim exists for the user context, the associated element is displayed. Otherwise, the element is not shown. We also need to track any changes on the claims, so we need to add a $scope.watch to evaluate the existent of our claims as we remove or edit them. Note that this watch is only added here to demo the behavior of editing the claims. On a live system, this would usually happen only when the user logs out as this resets his security context.
On the HTML tab, we only need to add the ngShow directive with the corresponding controller variable. For the the delete button, we use the ctrl.deleteAccess variable. For the edit button, we set the directive to the ctrl.editAccess variable.
Does It Work?
To check that this is working properly we can run a simple test. Run JSFiddle and delete both app.edit and app.delete claims. These should essentially remove all the icons on our list as shown below:
Areas of Improvements
This implementation was a lot simpler than having to use a directive, but it also has a big flaw. We can imagine an app with several controllers, and we need to do implement the claim validation logic in many of them. For those cases, we definitely would like to use some reusable component instead of adding the same code on the controller.  When the view has multiple elements like menus  and each menu has an independent claim/permission, we probably want to use the auth directive. For cases, when multiple elements are controlled by the same claim, we may just want to use the auth isolate directive.

Originally published by ozkary.com