<!DOCTYPE html>
<html ng-app="authentication">

<head>
  <script data-require="angular.js@*" data-semver="1.2.10" src="http://code.angularjs.org/1.2.10/angular.js"></script>
  <script data-require="angular-route@*" data-semver="1.2.10" src="http://code.angularjs.org/1.2.10/angular-route.js"></script>
  <script src="script.js"></script>
  <link rel="stylesheet" type="text/css" href="style.css">  
</head>

<body>
  <div ng-controller="AuthCtrl">
    <label for="hasAdminRights">
      <input type="checkbox" name="isLoggedIn" ng-model="giveAdmin" ng-change="updateRights()" /> has admin rights
    </label>
  </div>
  
  
  <hr />
  
  <ul>
    <li><a href="#/home">Home</a></li>
    <li><a href="#/admin">Admin</a></li>
  </ul>
  
  <hr />
  
  <div ng-view></div>
</body>

<script type="text/ng-template" id="home.html">
  <h1>Home</h1>
  <p>Welcome to this authentication demo with AngularJS!</p>
</script>

<script type="text/ng-template" id="admin.html">
  <h1>Admin</h1>
  <p>Welcome to the admin screen!</p>
</script>

<script type="text/ng-template" id="login.html">
  <h1>Login</h1>
  <p>Access denied! Please log in.</p>
</script>

</html>
angular.module('authentication', ['ngRoute'])
  .service('authService', ['$rootScope', function($rootScope) {
    this.rights = [];
    
    this.addRight = function(right) {
        if (!this.hasRight(right)) {
            this.rights.push(right);
        }
    };
    
    this.removeRight = function(right) {
        if (this.hasRight(right)) {
          this.rights.splice(this.rights.indexOf(right), 1);
        }
    }
    
    this.hasRight = function(right) {
        return this.rights.indexOf(right) !== -1;
    }

  }])
  .config(['$routeProvider', function($routeProvider) {
      var checkRight = function(right) {
    		return ['$q', 'authService', '$location', function ($q, authService) {
    			var retDef = $q.defer();
    
    			if (authService.hasRight(right))
    				retDef.resolve();
    			else
    				retDef.reject({invalidRights: true, rightRequired: right});
    
    			return retDef.promise;
    		}]
    	}
    
    	$routeProvider.whenHasRight = function(right, path, route) {
    		route.resolve = route.resolve || {};
    		route.resolve.hasRight = checkRight(right);
    		return $routeProvider.when(path, route);
    	};

      $routeProvider
        .when('/home', { templateUrl: 'home.html' })
        .when('/login', { templateUrl: 'login.html', controller: 'LoginCtrl' })
        .whenHasRight('ADMIN', '/admin', { templateUrl: 'admin.html' })
        .otherwise({ redirectTo: '/home' });
    }
  ])
  .run(['$location', '$rootScope', '$log', 'authService', '$route',
    function($location, $rootScope, $log, authService, $route) {
      $rootScope.$on('$routeChangeError', function(ev, current, previous, rejection) {
        
        if (rejection && rejection.invalidRights === true) {
    			alert(rejection.rightRequired + ' rights required!');
    			
    			$location.path('/login');
    		}
        
        
      });
    }
  ])
  .controller('LoginCtrl', ['$scope', '$location', function($scope, $location) {
    $scope.returnUrl = $location.search().returnUrl;
  }])
  .controller('AuthCtrl', ['$scope', 'authService', function($scope, authService) {
    $scope.updateRights = function() {
      if ($scope.giveAdmin)
        authService.addRight('ADMIN');
      else
        authService.removeRight('ADMIN');
    }
  }]);
# How it works

This adds a function, `whenAuthenticated()` to the `$routeProvider`. You can use that to define your routes that needs authentication (as opposed to `when()`).

The function adds a resolve dependency to the route that will check if the user is authenticated or not.

If the resolve promise is rejected (see the `isLoggedIn` function in the `config` block), the `$routeChangeError` will be emitted.
From there you can examine the result of the promise and optionally redirect to a login/access denied page.
ul {
  list-style-type: none;
  margin: 0;
  padding: 0;
}

li {
  display: inline;
}