Saturday, August 13, 2016

AngularJS SPA Route Claims Authorization


Overview 

When we talk about routing with AngularJS, we make reference to a service that allows us to map URL routes to view templates (HTML) and controllers. This is what allows a single page application to navigate to different areas of the app.

In the context of authorization, we need to allow access to protected routes/views to only the users with the corresponding claims or access. This is even if the user attempts to force load the route by typing the URL or running a command on the browser console.

Route Specifications

In order to control the authorization of the routes, we must first understand the claims that are assigned to secure our routes. There may be some routes that have public access and required no claims. For the secured routes, we need to be able to know the claim value that should be used to verify the access. As an example, let’s take a look at our route specifications:

Route
Claim
Required
/login
no
/claims
app.claims
yes

The specifications indicate that the app has two routes. The /login route has public access, as it is needed to allow the users to login to the app. The /claims route requires the app.claims claim to be present in the user security context. Let's take a look at our JSON model which represents our route information with the corresponding claims:


var appRoutes = [{
            title: "Login",
            url: "/",          
            templateUrl: "views/main.html",
            controller:null,
            controllerAs: null,          
            requiredAuth: false         
        },
        {
            title: "Claims",                //todo-auth add claims module
            url: "/claims",
            templateUrl: "views/claims.html",
            controller: "app.ctrl.claims",
            controllerAs: "ctrl",
            redirectTo: '/noaccess',
            claims: "app.claims",
            requiredAuth: true
          
        ];



The claims and requiredAuth attributes are used to check if the route should be protected, and if so, what claim should be used to validate for the access. We look at this in more detail on our route implementation later on.

Configuring Routes

We start our implementation by defining our module and configuring our routes. The route configuration is usually done in the app.config function where we can inject the routeProvider (ng-route) or stateProviders (ui-router). In our case, we are using routeProvider, so our implementation looks as follows:


function appConfig($routeProvider, $appRoutes) {

            $appRoutes.forEach(function (route) {
                configRoute(route);
                function configRoute(route) {
                    $routeProvider
                        .when(route.url, {
                            templateUrl: route.templateUrl,
                            controller: route.controller,
                            controllerAs: route.controllerAs,
                           
                        });
                }
            });

            $routeProvider.otherwise("/");
 }


We have defined the $appRoutes JSON which contains the application route definition with view, controller and claim association. This has the necessary information to wire our routes. For now, our current implementation just handles the routing to different areas of the app. There is no restriction on the access. We can implement the security/authorization next.

Authorize Routes- Resolve

For authorization, we rely on an authorization service which sets the user context with the corresponding claims. For now, we just simply set the claims with the service as a property. For a production app, there should be integration with an identity provider.

During the app configuration phase, we can inject the authorization service ($svcAuth) to the route configuration. We add the security validation to the routeProvider resolve function which waits for a promise to resolve successfully before the route changes. This allows us to verify the access before the route changes and presents the view to the user.

In cases when the required claim does not exist in the user context, we terminate the route change by throwing an error. Otherwise, we resolve the call to true which allows the route to change successfully.

  
resolve: { 
"hasClaim": ["app.svc.auth", "$route", function ($svcAuth, $route) {
                  var result = false;
                   if (route.requiredAuth) {
                     var result = $svcAuth.hasClaim(route.claims);
                         if (!result) {                                      
                               $route.current.noAccess = route.redirectTo;
                               throw new Error('No access to route: ' + route.url);                                                                               
                         } else {                                       
                              $route.current.noAccess = null;                                       
                        }
                     }
                     return result;
 }]
}


We can now take a look at our complete implementation with the authorization enhancements.




Authorize Service

For this implementation, the auth service is used by the configuration phase of the application. When configuring our routes, we use the auth service to validate the user claims during the route resolve call. The auth service can also be used with other components like directives and controllers.



Does it Work?

To test if this is working, we can delete the app.claims claim from the /claims route by visiting the claims view and clicking on the trash can icon. We can then navigate back to home (menu) and try to click on the claims menu link again. Since the claim is removed, we should get an error which can be seen on the browser console, and the app would no longer navigate to the claims view.



Areas of Improvements

We should notice that during the resolve route process, we raised an error to terminate the route. This is not really an elegant way to signal to the user that he/she has no access to that area of the application. We could do better by redirecting the user to an area of the application that can provide a detail message.


Coming Soon Read about redirecting users for an authorized routes



We should also notice that we are displaying the navigation menus without any security validation. Since we know the user context, we could secure our navigation menu and avoid unauthorized clicks on the app. This would be a much better user experience and additional layer of authorization.


Coming Soon Read about Navigation menu claims authorization




Hope this help us in protecting our routes.

Originally published by ozkary.com

Saturday, August 6, 2016

SharePoint 2013 App domain for this site has already been assigned

When deploying a SharePoint 2013 add-in (or app) from Visual Studio, we may get the following error:


ErrorDetail: The content database on the server is temporarily unavailable
ErrorType: Transient
ErrorTypeName: Intermittent
ExceptionMessage: The App domain for this site has already been assigned

This error is usually a result of an add-in prefix update on the farm.  When we configure the on-premises development environment for SharePoint add-ins, we need to provide a prefix to our apps. This prefix is used as a subdomain name for the app.

Domain
Description
ozkary.com
Domain name
app.ozkary.com
App subdomain name. app is the add-in prefix that was configured on the farm.

Set up SharePoint on premise development environment


https://msdn.microsoft.com/en-us/library/fp179923(v=office.15).aspx



Solution
To solve this problem, we need to make sure that the service returning this error is re-started after making the prefix change. If we are sure that our prefix is correct (see the URL on the browser when loading a different app from SharePoint), we just need to restart the service. Otherwise, run the command (PowerShell) to update the prefix and re-start the service as shown in the next steps:
Update the add-in prefix
This is the command to update the add-in prefix (SharePoint Management Shell). Notice the word “app”. This is the prefix.

Set-SPAppSiteSubscriptionName -Name "app" -Confirm:$false

Re-Start the service
These are the commands to re-start the service (stop/start). Run this command from the windows command shell (use Run as Administrator).


net stop sptimerv4

net start sptimerv4

Provided that there are no errors, we should be able to go back to Visual Studio and deploy the app.
Originally published by ozkary.com


Sunday, July 24, 2016

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

Sunday, July 17, 2016

AngularJS SPA Isolate Scope Directive Claims Authorization

Overview
In a previous article, we discussed the use of directives to enable claims based authorization on some the user interface elements. For some scenarios, a directive is the ideal approach, but because of the fact that a directive is called every time is declared on the mark-up, it is not ideal for cases where an item lists can have many items, and we just need to validate one or two claims.

Directive Implementation
When looking at our previous implementation, we can see on the console windows the number of times that the directive is called. We want to optimize the approach by just calling the directive one time and validate the claims for the user.  A way to do this on AngularJS is by using an Isolate Scope Directive.  This means that the directive does not share the same scope as the controller, but it also provides the advantages that we can pass object references and functions which can be used to indicate what claims need to be validated all at once thus eliminating the additional calls.
New Approach Isolate Scope
Now that we understand our optimization approach, we can refactor our code by first removing the authorize directive from the button markup which is what causes the multiple directive calls. We can now define our new directive with isolate scope and restrict it to “E” which means that it can be used as an element only. The idea here is that we want to declare it only one time on the mark-up outside the ngRepeat scope.  
We also want to add two attributes to our element. These attributes are assigned to functions within the controller. We should notice that in order to pass evaluating expressions to our directive, the attributes need to be declare with “&”.

scope: {
                  authorizeMapping: '&',
                  authorizeCallback: '&',                   
      },//isolate scope    

The function assign to the authorize-mapping attribute returns a JSON with all the claims that need to be validated on behalf of that controller. The function assign to the authorize-callback attribute is called by the directive to return the status of each claim (true when found). Let’s take a look at our new implementation:


Controller Kicks In
Once the controller has received the status of each claim, we can leverage the power of AngularJS by mapping claims to controller variables. At this point, we just need to add an ng-show directive and assign a controller variable to evaluate if the user is authorized to see that element. Yes, we are still using a directive for each element, but that is just evaluating a true or false expression, and it is not calling the authorization service to validate the claim.
We can now compare the console output with the isolate scope, and we should see that we no longer have multiple calls to our directive. The result should be just one entry.


Does It Work?
To check that this is working properly we can run a simple test. Run JSFiddle and set the app.edit claim value to an empty string or just click the delete icon. This should remove the permission on the rest of the list items as shown below.
Areas of Improvement
As usual, we should ask ourselves if there ways of improving this approach. Since we can now notice that this solution uses controller variables, do we really need a directive? If the concern is reusability, the directive approach is preferred over a controller only implementation as this can create code duplication. To show this, we can review the controller only solution on another article.

Originally published by ozkary.com

Sunday, July 10, 2016

AngularJS SPA Directive Claims Authorization

Overview
When we talk about authorization of the elements on a web application, we make reference to the ability to hide or show some areas of the application based on the permissions that are granted to the logged on user.  These permissions are usually delivered to the application via claims on a security token like a JSON Web Token (JWT).
Security Service
For now, we assume that the claims have been populated in our 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. The purpose for this service is to be used by all controllers, directives and other services that require authorization services.
Specifications
We want to be able to create a simple user interface that contains a list of items with two action item buttons.  The delete button allows us to remove the item from the list. The edit button is used to edit the item information.   In order to understand what claim controls the access to what element, we must have some information that indicates what needs to be done.  The table below provides the information that we need. If the user has the respective claim, we display the element. Otherwise, we remove it from the DOM.
Element
Claim
Action
Delete Button
app.delete
Display the element
Edit button
app.edit
Display the element


Implementation
Now that we understand what claim and elements we need to look for, we can take a look at our app.  The image below shows a simple list with items. Each item has a delete and edit button. This maps well with what has was been defined on our specifications.
When using AngularJS, the recommended approach to change element behavior is by using directives.  With that in mind, we can implement an Authorize directive which takes a tag value. This tag is the actual claim value that can be used by the directive and the authorization service to verify that the user has the required claim.  Let’s take a look at our implementation next:

On the HTML tab, we have added the authorize directive with the respective claim tag for each of the call to action buttons (delete, edit). On the JavaScript tab, we can see our directive implementation (dirAuth) .  We read the claim tag from the element attributes and pass it as an argument to the auth service ($svcAuth).  If the claim is found on the claims collection, the result is set to true, and we show the element. Otherwise, we hide it.
Does It Work?
To check that this is working properly we can run a simple test. Run the JSFiddle and click on the delete icon for either the delete or  edit claim. We should see how all the icons for the remaining rows are no longer available. In the image below, the app.delete claim was removed. We could also just empty the claim value as this would evaluate as false and would remove the permission on the control.
Areas of Improvements
That was fairly easy to secure, but there is something there that bothers me a bit.  If we take a closer look, we can see that this list has multiple items, and each item has a delete and edit call to action buttons. As we can image, the directive will be called each time it is declared in the mark-up. In this example, there are five items with two buttons. This means that our directive will be called 5X2 times (n x 2 for any list).  We can see this by adding a trace call on the code and looking at the console window:
As suspected, our directive is called too many times, but we just need to check for two claim values. Clearly for this scenario, we need a better approach. We can address this concern by using a directive with isolate scope, but we can leave that for another article.

Originally published by ozkary.com