Build A Secure Angular App Using MSAL And Azure Active Directory

Introduction

In the previous article, we will learn how to create an Angular 11 app with .NET 5 API that can do CRUD operations on Azure Cosmos DB using EF Core. We will continue this article add authentication to the app using Microsoft Authentical Library (MSAL). The app we will be using in this example also supports live data refresh. If you want to integrate that please make sure to check out this article.

Prerequisites 

  • Azure account - If you don't have it already you can create one for free by visiting Cloud Computing Services | Microsoft Azure
  • Azure Cosmos DB Setup - Create a database in Azure Cosmos DB called VideogamesDB and a container called Videogames. If you want step-by-step instructions on how to do that please follow this article
  • .NET 5 REST API - Please follow this article to create .NET 5 REST API
  • Angular CLI version 11. You can check the installed version using the command ng version. 
  • Visual Studio Code or any other IDE. If you don't have VS Code installed you can download it from here
  • A working angular app we built in this article

Step 1 - Register your app on Azure Active Directory

1. Log in to the Azure portal and click on Azure Active Directory. If you don't see that option on your home page you can also search for it by typing it in the search bar

Register app on Azure Active Directory

2. Click on the "App Registration" option on the left menu and click on "New Registration" option on the top of the page

Register app on Azure Active Directory

On the App registration page 

  • Give a display-name, it can be any relevant name of your choice.
  • Choose a supported account type, i have selected the option that will allow any kind of Microsoft account to login
  • Give a redirect URI option. Here select the app type as SPA because we are authenticating an angular app which is a single page application and in redirect URI gives the URL of your home page. Since our app is local so I gave the URL as "http://localhost:4200"
  • Click the Register button

Register app on Azure Active Directory

If everything goes well app registration will be created and a new page will be loaded. We need the Application (Client) ID from there which we will be using in our angular app.

Register app on Azure Active Directory

Step 2 - Add MSAL for Angular

1. Open VS Code and go to the angular project we developed in our previous article. Go to terminal and run the following command to install packages

npm install @azure/msal-angular @azure/msal-browser

2. Open app.module.ts file. Here we will have to configure MSAL for angular. It can be done in several ways. We will be using Factory providers to provide configuration option

  • Add MsalModule to imports array

    Add MSAL for Angular
     
  • Add a new method MSALInstanceFactory. Copy-paste the following code 

    Add MSAL for Angular

    Here clientId should match the Application (Client) ID we generated in Azure in the previous step.
  • Add provider and MsalService to providers array

    Add MSAL for Angular

Note: For more configuration options and understanding please refer to official Github link here.

Step 3 - Add Angular Guard

1. To prevent users from accessing the routes without login we will create guards. Run the following command on terminal 

"ng g guard userauthguard" and choose CanActivate

Add Angular Guard

2. Open userauthguard.guard.ts file and copy-paste the following code.

We have created a constructor and added an instance of MsalService. We are using the instance in CanActivate method to check if there is an active account (which indicates the user is logged in or not) currently. If yes then the user should be allowed to access the guarded routes.

import { MsalService } from '@azure/msal-angular';
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate, RouterStateSnapshot, UrlTree } from '@angular/router';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class UserauthguardGuard implements CanActivate {
  
  constructor(private msalService:MsalService)
  {

  }
  canActivate(
    
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
      
      if(this.msalService.instance.getActiveAccount()!=null)
      {
        return true;
      }
      else
      {
        return false;
      }
     
  }
  
}

Step 4 - Guard your routes

We don't want the unauthenticated users to add new video games or edit existing video games. Go to app.routing.module.ts and add the canActivate property for the routes we want to guard. canActivate is an array so we provide the name of the guard we just created and Guard word is added to the name by default so it will be a good idea not to use the word guard in the file name as I did!

Guard your routes

Step 5 - Hide the links which are inaccessible

Now to avoid any confusions we will hide the links which are not accessible to unauthenticated users using ngIf.

1. Go to app.component.html and replace the router link for adding new videogame with the code mentioned below. Notice we have added *ngIf="isUserLoggedIn()"

<a routerLink="/videogame-edit" routerLinkActive="active" class="navbar-brand " *ngIf="isUserLoggedIn()">Add New Videogame</a>

2. Go to videogamelist.component.ts and add a new method as shown below. Also, add an instance of the MsalService to the constructor.

 isUserLoggedIn():boolean
  {
    if(this.msalService.instance.getActiveAccount()!=null)
    {
      return true;
    }
    return false;
  }
constructor( private service: VideogameserviceService, private router: Router,private http: HttpClient,private msalService:MsalService) { }

3. Go to videogamelist.component.html file and replace the edit and delete button code with the following. Notice we have added *ngIf="isUserLoggedIn()"

<td><button render="renderer" id="editbutton" (click)="editbuttonclicked(videogame.id)" class="btn btn-primary" *ngIf="isUserLoggedIn()">Edit</button></td>  
          <td><button render="renderer" id="editbutton" (click)="deletebuttonclicked(videogame.id)" class="btn btn-primary" *ngIf="isUserLoggedIn()">Delete</button></td>            

 Step 6 - Test your code

1. Go to terminal and type ng serve -o to launch the app. If everything goes well you will notice that on the home page you get a login link and also the link to add video games is not present. Also, the edit and delete buttons are not visible

2. Click on Login and it should open a popup for you. Enter your Microsoft credentials

3. Once you are logged in successfully, you should be able to add/edit/delete video games. To logout again, click on the Logout link

Summary

In this article, we learned how to authenticate users with Microsoft login using MSAL and Azure Active directory. Please note that although our front-end app is secure, our rest API service is still not secure and doesn't need authentication. In the upcoming article, we will see how we can solve this problem.

Thanks for reading and wish you a day filled with new coding adventures! Happy Coding!

Github Linkhttps://github.com/tanujgyan/angular-signalr-crud