9/17/16

Node.js Git Deployment in Azure App Service

When deploying a node.js app to azure there are a few tools that we can use to improve the deployment experience and enable the application to start properly under IIS.   Some of these tools involve the use of Git remote repository, IISNode and Kudu dashboard.
Deployment with Git

To facilitate the deployment using Git, we need to be able to push our code from our repository to a remote repository hosted by Azure. When we create an app on Azure, there are several options for the deployment source. This is what enables continuous integration on Azure. For us, we want to focus on the Local Git Repository option. To enable it, let’s follow a few steps.

Login to your Azure console and select your app then click on Settings > Deployment Source. Click choose source and select Local Git Repository. We now need to set our deployment credentials to enable our remote login. From Settings > Deployment Source, click on Deployment credentials and type a username and password which we need to be able to push our deployment.

Now that we have configured our app and deployment source, we need to get our Git URL which is available from your app Settings > Properties > Git URL.

Copy the URL and use Git to set a remote repository on your project by typing the following Git command or using your favorite Git tool from your local repository folder. For this step to work, you should be in the folder where a local Git repo has already been created. 


git remote add myRemoteRepo https://<username>@localgitdeployment.scm.azurewebsites.net:443/localgitdeployment.git 


This command creates a remote repo reference with the name myRemoteRepo. This name can be changed to anything. We just need to remember it as it is used when pushing to the repo. We also need to replace <username> with the username that we created when setting our deployment credentials.

Now that we have our repo configuration done, we can move forward and push our deployment to Azure master branch. From your local repo folder, type this command.


Git push myRemoteRepo master


Once the code is pushed to Azure, a build process takes place which deploys the remote master branch to the application folder.  This is where a bit of magic takes place which is required for node.js app to run on Azure.

What is IISNode?

This is a module that allows node.js to run on IIS. When a deployment is done on Azure, a web.config file is created automatically with the necessary entries to allow the application to start. To better understand this, let’s take a look at a web.config that is created:


<handlers>
    <!-- Indicates that the server.js file is a node.js site to be handled by the iisnode module -->
    <add name="iisnode" path="server.js" verb="*" modules="iisnode" />
</handlers>
<rewrite>
    <rules>
        <!-- Do not interfere with requests for node-inspector debugging -->
        <rule name="NodeInspector" patternSyntax="ECMAScript" stopProcessing="true">
            <match url="^server.js\/debug[\/]?" />
        </rule>

        <!-- First we consider whether the incoming URL matches a physical file in the /public folder -->
        <rule name="StaticContent">
            <action type="Rewrite" url="public{REQUEST_URI}" />
        </rule>

        <!-- All other URLs are mapped to the node.js site entry point -->
        <rule name="DynamicContent">
            <conditions>
                <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="True" />
            </conditions>
            <action type="Rewrite" url="server.js" />
        </rule>
    </rules>
</rewrite>

As we can see in the above markup, the iisnode handler is registered with IIS. The site entry point for the application is defined by the path attribute. In this example, it uses the server.js script as the entry point for our app.  The redirect rules are for the purpose of serving the static content like images, css as well as other resources like APIs or controller calls (dynamic content).

Kudu Dashboard

To check if our application is loaded, we can use the kudu dashboard on Azure. This tool is accessible from a special Url that points to our app. We just need to add the word SCM on theURL.

App Url
Myapp.azurewebsites.net
App Url for Kudu
Myapp.scm.azurewebsites.net

To login, we can use our Azure credentials. Once the console is loaded, we can visit the process explorer area of the console. There we are able to see that in addition to the w3wp.exe, there is also the Nodejs process loaded.



I hope this article can help you on having a better understanding on the deployment of Node.js apps on Azure.

Originally published by ozkary.com

9/10/16

AngularJS SPA Navbar Authorization



In a previous article, we covered how to protect application routes with security claims which is the process that allows us to control a user access based on assigned permissions. During our implementation, we realize that there are some areas of improvement. The most clear one is that are we showing navigational links to the users when they may not have the necessary authorization to see those elements. To improve that, the obvious approach would be to just hide those links and avoid any unnecessary user clicks.

Route Specifications

A basic approach to protect any user interface on an app is to add a directive to the UI elements. But before we start adding a directive, we need to know what claim determines if a user has access to a specific element. For that, we need to understand our application route specifications. In our example below, we can see that the /claims route requires a security claim.

Route
Claim
Required
/login

no
/claims
app.claims
yes
/noaccess

no

Now that we understand what claims are required for authorization, we can focus on how to build our menus based on the route specifications.  If we take a look at our static inline implementation of the navbar, we can see that our HTML looks like this:


  <div class="collapsed navbar-collapse" id="app-menu">
        <ul class="nav navbar-nav">
           <li clas='active'><a href="#/"><i class="fa fa-home"></i> Home</a></li>
           <li><a href="#/claims"><i class="fa fa-key"></i> Claims</a></li>
        </ul>
 </div>      


We could work with this HTML and add our directive there, but if our route configuration changes, we will need to modify the HTML to match that change. We could do much better and just use the route configuration to build our navbar dynamically. Let’s take a look at that.

Use Route Configuration to Build the Menus

In our static implementation, we define the menu links without mapping them to the actual routes.  In order to leverage the route information for our menus, we need to build the menu links dynamically. We can do this by adding a controller that can manage the menu for us. 
In some cases, we may not want to display all the routes on the menu. This is the case for the /noaccess route which is intended to be displayed just when there are errors, but not for the user to see it and click it.

We can control the visibility of menus by adding a show property on our routes configuration. This can be used to show/hide the element using the ngShow directive. Our route configuration should look as follows:


var appRoutes = [{
            title: "Login",
            url: "/",          
            templateUrl: "views/main.html",
            controller:null,
            controllerAs: null,          
            requiredAuth: false,
            show: true,
            icon: 'fa-home'
        },
        {
            title: "Claims",                            url: "/claims",
            templateUrl: "views/claims.html",
            controller: "app.ctrl.claims",
            controllerAs: "ctrl",
            redirectTo: '/noaccess',
            claims: "app.claims",
            requiredAuth: true,
            show: true,
            icon:'fa-key'          
        },
        {
            title: "No Access",
            url: "/noaccess",           
            templateUrl: "views/noaccess.html",
            controller: null,
            controllerAs: null,
            requiredAuth: false           
        }];


Only the Login and Claims routes are set to show:true.  We can now continue to build our controller and build our navbar dynamically.


app.controller('app.ctrl.menu', ['$appRoutes', ctrlMenu]);

function ctrlMenu($appRoutes, $svcAuth) {
            var ctrl = this;
            ctrl.menu = $appRoutes;
 }
    

 The menu controller is very simple. We only need to inject the route configuration. On the view, we declare our controller and use the ngRepeat directive to iterate the items in the array. Our new dynamic menu mark-up should look as follows:


<div class="collapse navbar-collapse" id="app-menu">
     <ul class="nav navbar-nav" ng-controller="app.ctrl.menu as ctrl">
         <li ng-repeat="item in ctrl.menu">
           <a href="{{item.url}}" ng-show="item.show">
             <i class="fa {{item.icon}}"></i> <span ng-bind="item.title"></span>
           </a>
           </li>                                                           
       </ul>
</div>


Authorize Directive

We are now ready to add the authorize directive to our menus.  As we declare the directive on the markup, we pass the menu:claims property. This is what can enable us to control the visibility of the menus based on the user’s permissions. Our new change looks like this:


<li ng-repeat="item in ctrl.menu">
  <a authorize="item.claim" href="{{item.url}}" ng-show="item.show">
      <i class="fa {{item.icon}}"></i> <span ng-bind="item.title"></span>
   </a>
</li>   



app.directive("authorize", ['app.svc.auth', dirAuthorize]);
        function dirAuthorize($svcAuth) {
            return {
                restrict: 'A',
                scope: {
                    authorize: '='
                },              
                link: function (scope, elem, attrs) {

                    var watch = function () {
                        //get the claim value
                        var claims = scope.authorize;

                        if (claims) {
                            var result = $svcAuth.hasClaim(claims);
                            if (!result) {
                                elem.hide();
                            }
                        }
                    };
                    watch();                    
                }
            };
 };


The Authorize directive handles the authorization logic. It reads the claim value, and it uses the $svcAuth services to find out if there is a claim with the same value in the user context. If the claim is found, the element is displayed, and we should feel confident that the same validation should succeed during our route authorization. If the claim does not exist, the menu link should not be visible, and the user would not be able to attempt to navigate to that area of the application.

Note

We need to note that this is only removing un-authorized elements from the user interface. This is just to improve the user experience by preventing un-authorized clicks. We still need to make sure that the route that is executed on a click is also protected.

Does It Work

We can take a look at our example below. As we can see all the menus are visible for now because the corresponding claims exists. To test it, we can click on the claims menu item and delete the app.claims entry by clicking on the trash can icon. As the claim is removed, the menu entry should also be removed because we are essentially removing the claim from the user security context.







That was a fun series of blog entries on claims based authorization. We now are able to protect our routes, redirect unauthorized users and add authorization to user interface elements all using the same reusable components. 








Originally published by ozkary.com