Angular How-to: Implement Role-based security

Premier Developer

Premier

Laurie Atkinson, Premier Developer Consultant, shows us how to customize the behavior of an Angular app based on the user’s permissions. This includes page navigation, hiding and disabling of UI elements, and generation of menus.


Applications often include requirements to customize their appearance and behavior based on the user’s role or permission. Users should only be presented with certain choices based on their role or a set of actions they have permission to perform. This is not a replacement for securing the data at the API level, but improves the usability on the client. This post provides sample code that you can use to implement this feature in your Angular app.

Create an authorization service

Centralize the checking of permissions into an Angular service.

authorization.service.ts

authorization.types.ts

Create attribute directives to hide and disable elements

To hide or disable an element based on permission, use the following code to create two directives. This will enable the Angular templates to use this syntax:

disable-if-unauthorized.directive.ts

hide-if-unauthorized.directive.ts

Create a CanActivate guard to prevent unauthorized routing

Angular includes a feature to prevent navigation to a page by implementing a CanActivate guard and specifying it in the route configuration. Unfortunately, there is no option to pass a parameter into the guard service, but a work-around is to use the data property of the route. When using this CanActivate guard in the route table, the programmer must also provide the route data value. This example uses a value named auth.

auth-guard.service.ts

Include the canActivate property of the route definition together with the data property in order to pass in the required permission.

routing.module.ts

Call the authorization service elsewhere in the app

In addition to the attribute directives and the CanActivate guard for routing, the authorization service can be called throughout the app. For instance, a menu service could use the permission checking method to hide menu items if the user does not have the required permission.

menu.service.ts

Remember, this is all merely JavaScript and a determined and savvy user could still work around these safeguards, but the goal is to improve the experience for the user. It is still the job of the serverside code to secure the data behind the API.

Premier Developer
Premier Developer

Premier Support for Developers

Follow Premier   

2 comments

    • Avatar
      Laurie Atkinson

      That service should call an API that returns a list of permissions. Something like this:
      export class AuthorizationDataService {
          constructor(httpClient: HttpClient) {}    getPermissions() {
              const endpoint = ${this.apiServer.metadata}authorizations;
              return this.httpClient.get<Array<ActionCode>>(endpoint).toPromise();
          }
      }
      I have a completed solution that contains a number of features, including this authorization example. It is posted here: https://github.com/laurieatkinson/ng-patterns-demo

Leave a comment