Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JWT Authentication in Angular - Multiple authentication levels

I am building an angular app with a sails.js backend. I've incorporated this JWT authentication into the app.
https://github.com/Foxandxss/sails-angular-jwt-example

I am still exploring exactly how the authentication works and I am currently trying to figure out how to add multiple authorization levels. It comes pre-built with 0 and 1, and I want to add an admin level above that.

It handles the existing authorization levels as follows: Each route is assigned an authorization level, via a constant. So all user routes get this access property assigned at the data property in the state:

    $stateProvider
          .state('user', {
            abstract: true,
            template: '<ui-view/>',
            data: {
              access: AccessLevels.user
            }
          })

The AccessLevels.user is pulled from a constant key-value pair:

angular.module('app')
  .constant('AccessLevels', {
      anon: 0,
      user: 1
  });

Whenever a route is navigated to, it checks the data.access property to see what the access level is for that particular route. If it comes back as a route requiring authentication, it checks localStorage for a token. If there is a token, the route proceeds, otherwise it boots you.

Here is the function that is called on stateChangeStart:

authorize: function(access) { //<- 'access' will be whatever is in the data property for that state
        if (access === AccessLevels.user) {
          return this.isAuthenticated(); // <- this just grabs the token
        } else {
          return true;
        }
      }

So what is the simplest way to add an additional layer?
I obviously need to put auth_level value into the user model. But then what? What would be the best way to add this functionality and maintain the integrity of the existing authentication (I am concerned about security)?

like image 290
tpie Avatar asked Oct 20 '22 14:10

tpie


1 Answers

You can use private claims to hold authorizations granted by the server. Private claims let you put whatever other sorts of data in JWT that you want.

I've never used node-jsonwebtoken (which appears to be what sails.js uses for JWTs), but it looks like you can just work directly with the JWT payload to access values that you would expect to be present, so you could do something like this:

// Assign authorization on server after successful authentication of an admin
token.auth = AccessLevels.admin;

// Read authorization on client
authorize: function(access) {
    if (access === AccessLevels.anon) {
        return true;
    }
    // Assumes the JWT token is returned by isAuthenticated()
    // (Sorry, not familiar with Sails.js or the JWT example)
    return this.isAuthenticated().auth === access;
}

After authentication, any subsequent request should verify the user's authorization as well, probably by adding an addition policy similar to "tokenAuth" in the example you provided, but that verifies the auth claim on the supplied JWT matches the authorization required to invoke whatever function is about to be called.

like image 72
Erik Gillespie Avatar answered Oct 22 '22 22:10

Erik Gillespie