Securing AngularUI Router states

Angular routers

  • Simple: ngRoute
  • More complex: ui-Router
  • Future: angular-new-router

ngRoute

$route / $routeProvider

ngRoute

  • Core module
  • Based on routes
  • Very Limited: Single level routing

Ui-Router

$state / $stateProvider 
& $urlRouterProvider

place within your app

Nested hierarchy

Names are names

Navigate by name or url

Multiple views (ui-view)

Populate any view

State populates 'parts'

url within your app

Flat hierarchy

Names are urls

Navigate by url only

Single view (ng-view)

Populate the one view

Directives  populate 'parts'

States vs. Routes

Defining states

$stateProvider
    .state('app.article', {
        url: '/articles',
	abstract: true,
	template: '<ui-view/>'
    })
    .state('app.article.list', {
        url: '',
	controller: 'ArticleListController as listCtrl',
	templateUrl: 'list.tpl.html'
    })
    .state('app.article.item', {
	url: '/{id:int}',
	abstract: true,
	controller: 'ArticleItemController as itemCtrl',
	templateUrl: 'item.tpl.html',
	resolve: {...}
    })
    .state('app.article.item.view', {
	url: '',
	templateUrl: 'item.view.tpl.html'
    })
    .state('app.article.item.edit', {
	url: '/edit',
        templateUrl: 'item.edit.tpl.html'
    });

1. /articles

Article State

List state

2. /articles/5

Item state

View State

Securing Ui-Router states

Requirements

  • A way to mark application states as secured;
  • A way to set permissions for secured states;
  • A way to mark default states for further redirection; 
  • A way to log out the user if he can not activate any state.
  • A way to remove html parts if the user it's not authorized to see them;
  • A way to remember the requested state when user it's not authenticated;

Table of contents

  • Defining State Security
  • Navigation Interception
  • Securing UI Elements

Defining State Security

$stateProvider
    .state('app.article', {
        url: '/articles',
	abstract: true,
	template: '<ui-view/>'
    })
    .state('app.article.list', {
        secured: ['ITEM_VIEW'], // <<<---
        canBeActivated: true, // <<<---
        url: '',
	controller: 'ArticleListController as listCtrl',
	templateUrl: 'list.tpl.html'
    })
    .state('app.article.item', {
	url: '/{id:int}',
	abstract: true,
	controller: 'ArticleItemController as itemCtrl',
	templateUrl: 'item.tpl.html',
	resolve: {...}
    })
    .state('app.article.item.view', {
        secured: ['ITEM_VIEW'], // <<<---
	url: '',
	templateUrl: 'item.view.tpl.html'
    })
    .state('app.article.item.edit', {
        secured: ['ITEM_VIEW', 'ITEM_UPDATE'], // <<<---
	url: '/edit',
        templateUrl: 'item.edit.tpl.html'
    });

Navigation Interception

angular
    .module('app')
    .run([
	'$rootScope'
        function securityRouteInterceptorConfig($rootScope) {
	    $rootScope.$on('$stateChangeStart', _routeInterceptor);

            /**
    	     * @private
    	     *
    	     * @description
    	     * `$stateChangeStart` event handler
    	     * Checks that current user can activate a state
    	     *
    	     * @param {Object} event object
    	     * @param {Object} toState - destination state config object
    	     * @param {Object} toParams - destination state params object
    	     * @param {Object} fromState - source state config object
    	     * @param {Object} fromParams - source state params object
    	     */
    	    function _routeInterceptor(event, toSt}, toParams, fromState, fromParams) {
                ...
            }
    ]);

Securing UI Elements

<ul class="nav nav-pills nav-stacked">
    <li ui-sref-active="active" secured="'ITEM_VIEW'">
        <a ui-sref=".view">View mode</a>
    </li>
    <li ui-sref-active="active" secured="'ITEM_VIEW, ITEM_UPDATE'">
        <a ui-sref=".edit">Edit mode</a>
    </li>
</ul>

Demo Time

(Beware!!! ES6 goodies :-)

Credits

Securing AngularUI Router states

By Alexe Bogdan

Securing AngularUI Router states

Security for uiRouter states in an angular ES6 project

  • 1,795