1

I am having a lot of trouble determining how to add permissions / access-control to our Angular app. Right now we have this:

    app.config(['$stateProvider', function ($stateProvider) {

      $stateProvider

      .state('default', {
        url: '',
        templateUrl: 'pages/home/view/home.html',
        controller: 'HomeCtrl'
      })

      .state('home', {
        url: '/home',
        templateUrl: 'pages/home/view/home.html',
        controller: 'HomeCtrl',

        permissions: {                    // ?
          only: ['Admin','Moderator']
        },

        access: {                         // ?
         roles: ['*']
        },

        resolve: {                        // ?
          authenticate: function($state, $q, $timeout){

          },

        }

      })

}]);

I having trouble determining which methodology to use to create access control to each page.

Right now, the logged in user is stored in an Angular value:

app.value('USER', JSON.parse('{{{user}}}'));

The USER value contains the information about which roles / permissions the user has.

But I cannot inject USER into app.config() callback, it says "unknown provider".

How can I do access-control based of the USER parameters?

4
  • 1
    app.value() cannot be injected into a config block. : gist.github.com/demisx/9605099#value . Use app.constant() instead Commented Jun 9, 2017 at 17:15
  • cool, that's good to know, but for this case, using resolve.authenticate, we can inject anything, so don't need that solution tmk. Commented Jun 9, 2017 at 17:46
  • 1
    If you can update to UI-Router 1.0, a Transition Hook is the best way to accomplish this. Commented Jun 9, 2017 at 17:59
  • sure, add an answer and I will upvote Commented Jun 9, 2017 at 18:05

3 Answers 3

3

the key to perform that is to add your access control on an event $stateChangeStart

For example if you have your routing like that :

      .state('termsofuse', {
            url: "/terms",
            templateUrl: "termOfUse.html",
            resolve: {
                authorizedRoles: function() {
                    return [USER_ROLES['su'],
                        USER_ROLES['user'],
                        USER_ROLES['admin'],
                        USER_ROLES['skysu']
                    ]
                }

            }

        })

you may define your access controle like that

.run(
            function($rootScope, $q, $location, $window, $timeout) {

                $rootScope.$on(
                    '$stateChangeStart',
                    function(event, next, current) {                      

                        var authorizedRoles = next.resolve.authorizedRoles();

//this function controls if user has necessary roles
                      if (!isAuthorized(authorizedRoles)) {

                            event.preventDefault();
      // and I broadcast the news                                                     $rootScope.$broadcast("AUTH_EVENTS.notAuthenticated"); 


                        } else {
$rootScope.$broadcast("AUTH_EVENTS.loginSuccess");


                        }

                    })



            });

Then you just of to define your event's catcher to manager the desired behaviour (redirect / error message or whatever necessary)

Sign up to request clarification or add additional context in comments.

Comments

2

You might want to check out ngAA, I use it alongside ui-router.

Comments

0

This is how I got it to work. I am not sure if it's the best way, but it does work.

You cannot inject services/values in the app.config(), but you can inject services/values into the resolve.authenticate function.

I decided to use the resolve.authenticate methodology.

 .state('home', {
    url: '/home',
    templateUrl: 'pages/home/view/home.html',
    controller: 'HomeCtrl',
    resolve: {
      authenticate: handlePageRequest['home']   // <<<<
    }
  })

and then we have a handler:

  let handlePageRequest = {

    'default': function ($q, USER, $state, $timeout, AuthService) {
      // this page is always ok to access
      return $q.when();
    },

    'home': function ($q, USER, $state, $timeout, AuthService) {

      if(AuthService.isHomePageAccessible(USER)){
        return $q.when();
      }
      else{
        $timeout(function () {
          $state.go('not-found'); // we can prevent user from accessing home page this way
        }, 100);

        return $q.reject()
      }
    },
  };

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.