How to store and maintain user access roles


We have an application (C# on the server, using AngularJS / Web Apis for a single page application) that assigns users different roles, which are stored in the database. When the user logs in, the user object (including RoleID's and RoleName) is transformed into a JWT and sent to the user, which is then used as authentication.

We're having trouble determining the best way to maintain and use these access roles however. Specifically, to use them in the current set up, it would seem that we have to hard code either the name of the role or the ID into the application.

For example, on the client side, if we want only users with a Manager role to be able to see and click a button, we would have to explicitly state that, ie if (UserService.HasRole('Manager')) { doStuff(); }.

Conversely, we'd have to do the same thing on the server side (because everyone knows relying on client-side security is bad). When the server gets a request on the API, it checks the JWT for validity and, if valid, checks the User's roll to see if they are allowed access to the specific web API endpoint.

This all seems prone to breaking if a role is renamed, or the ID changes. I generally hate hardcoding things like this. Is there a better methodology or approach that can be taken here?

In the past, when we've done RBAC (Role Based Access Control), we decouple the Role from the Permission e.g.

Role               Permission
Manager            Create Order
Manager            Delete Order
Till Operative     Create Order
Administrator      Create User
Administrator      Suspend User


This could be stored in a database and cached in something like Redis. Two tables, Role and Permission, where the Permissions need to match the ones built into the application (you could script this).

So your permissions grow with your application e.g. you add a new dining service, you can add a "seat diners" permission. The permissions for existing/mature bits of the software should rarely change (unless they were written incorrectly), whereas the roles are entirely fluid and can be renamed etc.

You can then use an annotation/security framework to ensure that the user making each API call on the server side has the correct role required.

You can even make it additive and allow a user to occupy multiple roles at once to blend things together.

You may maintain your user to role mapping in the database also in another table (using FK constraints) or you may use something like LDAP with the mapping being looked up from the DB/cache.