or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

authentication-service.mdcomponents-module.mdevent-broadcasting.mdhttp-interceptor.mdindex.mdroute-protection.md
tile.json

route-protection.mddocs/

Route Protection

Route guard system for protecting Angular routes and ensuring user authentication before navigation, with support for redirect and popup interaction types.

Capabilities

MsalGuard

Route guard that ensures user authentication before allowing route activation, with configurable interaction types and authentication requests.

/**
 * Route guard for protecting Angular routes requiring authentication
 * Provides CanActivate, CanActivateChild, and CanMatch functionality
 */
class MsalGuard {
  /**
   * Determines if a route can be activated
   * @param route - The activated route snapshot
   * @param state - The router state snapshot
   * @returns Observable that resolves to boolean (allow navigation) or UrlTree (redirect)
   */
  canActivate(
    route: ActivatedRouteSnapshot, 
    state: RouterStateSnapshot
  ): Observable<boolean | UrlTree>;
  
  /**
   * Determines if child routes can be activated
   * @param route - The activated route snapshot
   * @param state - The router state snapshot
   * @returns Observable that resolves to boolean (allow navigation) or UrlTree (redirect)
   */
  canActivateChild(
    route: ActivatedRouteSnapshot, 
    state: RouterStateSnapshot
  ): Observable<boolean | UrlTree>;
  
  /**
   * Determines if a route can be matched during route resolution
   * @returns Observable that resolves to boolean (allow match) or UrlTree (redirect)
   */
  canMatch(): Observable<boolean | UrlTree>;
  
  /**
   * Parses URL string to UrlTree for navigation
   * @param url - URL string to parse
   * @returns UrlTree object for routing
   */
  parseUrl(url: string): UrlTree;
  
  /**
   * Builds absolute URL for destination page
   * @param path - Path to build URL for
   * @returns Absolute URL string
   */
  getDestinationUrl(path: string): string;
}

MsalGuardConfiguration

Configuration object for customizing MsalGuard behavior including interaction type and authentication requests.

/**
 * Configuration object for MsalGuard
 * Defines how the guard should handle authentication challenges
 */
interface MsalGuardConfiguration {
  /** Required interaction type for authentication (popup or redirect) */
  interactionType: InteractionType.Popup | InteractionType.Redirect;
  
  /** Optional authentication request configuration */
  authRequest?: MsalGuardAuthRequest | ((authService: MsalService, state: RouterStateSnapshot) => MsalGuardAuthRequest);
  
  /** Optional route to redirect to when login fails */
  loginFailedRoute?: string;
}

/**
 * Union type for guard authentication requests
 * Supports both popup and redirect request configurations
 */
type MsalGuardAuthRequest = Partial<PopupRequest> | Partial<Omit<RedirectRequest, "redirectStartPage">>;

Usage Examples:

import { NgModule } from "@angular/core";
import { RouterModule, Routes } from "@angular/router";
import { MsalGuard, MsalGuardConfiguration, MSAL_GUARD_CONFIG } from "@azure/msal-angular";
import { InteractionType } from "@azure/msal-browser";

// Define protected routes
const routes: Routes = [
  { 
    path: "dashboard", 
    component: DashboardComponent,
    canActivate: [MsalGuard]
  },
  { 
    path: "admin", 
    component: AdminComponent,
    canActivate: [MsalGuard],
    canActivateChild: [MsalGuard],
    children: [
      { path: "users", component: UsersComponent },
      { path: "reports", component: ReportsComponent }
    ]
  },
  { 
    path: "profile",
    loadChildren: () => import("./profile/profile.module").then(m => m.ProfileModule),
    canMatch: [MsalGuard]
  }
];

// Guard configuration
const guardConfig: MsalGuardConfiguration = {
  interactionType: InteractionType.Redirect,
  authRequest: {
    scopes: ["user.read", "openid", "profile"]
  },
  loginFailedRoute: "/login-failed"
};

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  providers: [
    { provide: MSAL_GUARD_CONFIG, useValue: guardConfig },
    MsalGuard
  ],
  exports: [RouterModule]
})
export class AppRoutingModule { }

Dynamic Authentication Requests

Configure authentication requests dynamically based on route or application state:

import { Injectable } from "@angular/core";
import { RouterStateSnapshot } from "@angular/router";
import { MsalService, MsalGuardConfiguration, MSAL_GUARD_CONFIG } from "@azure/msal-angular";
import { InteractionType } from "@azure/msal-browser";

// Dynamic auth request configuration
const guardConfig: MsalGuardConfiguration = {
  interactionType: InteractionType.Popup,
  authRequest: (authService: MsalService, state: RouterStateSnapshot) => {
    // Different scopes based on route
    if (state.url.includes('/admin')) {
      return {
        scopes: ["user.read", "directory.read.all", "group.read.all"],
        prompt: "select_account"
      };
    } else if (state.url.includes('/profile')) {
      return {
        scopes: ["user.read", "user.readwrite"],
        extraQueryParameters: { "domain_hint": "organizations" }
      };
    }
    
    // Default scopes
    return {
      scopes: ["user.read", "openid", "profile"]
    };
  }
};

@NgModule({
  providers: [
    { provide: MSAL_GUARD_CONFIG, useValue: guardConfig }
  ]
})
export class AppModule { }

Guard Usage with Different Interaction Types

Redirect-based Guard:

import { MsalGuardConfiguration } from "@azure/msal-angular";
import { InteractionType } from "@azure/msal-browser";

const redirectGuardConfig: MsalGuardConfiguration = {
  interactionType: InteractionType.Redirect,
  authRequest: {
    scopes: ["user.read"],
    redirectStartPage: window.location.origin + "/dashboard"
  }
};

Popup-based Guard:

import { MsalGuardConfiguration } from "@azure/msal-angular";
import { InteractionType } from "@azure/msal-browser";

const popupGuardConfig: MsalGuardConfiguration = {
  interactionType: InteractionType.Popup,
  authRequest: {
    scopes: ["user.read"],
    prompt: "select_account"
  }
};

Error Handling and Login Failed Routes

import { Component } from "@angular/core";

@Component({
  selector: 'app-login-failed',
  template: `
    <div class="error-container">
      <h2>Authentication Failed</h2>
      <p>Unable to authenticate your account. Please try again.</p>
      <button (click)="retry()">Retry Login</button>
      <button (click)="goHome()">Go to Home</button>
    </div>
  `
})
export class LoginFailedComponent {
  constructor(private router: Router) {}

  retry() {
    // Redirect to a protected route to trigger authentication
    this.router.navigate(['/dashboard']);
  }

  goHome() {
    this.router.navigate(['/']);
  }
}

// Configure guard with error handling
const guardConfig: MsalGuardConfiguration = {
  interactionType: InteractionType.Redirect,
  loginFailedRoute: "/login-failed",
  authRequest: {
    scopes: ["user.read"]
  }
};

Multiple Guard Configurations

For applications needing different authentication requirements for different route groups:

import { InjectionToken } from "@angular/core";
import { MsalGuardConfiguration } from "@azure/msal-angular";

// Create custom injection tokens
export const ADMIN_GUARD_CONFIG = new InjectionToken<MsalGuardConfiguration>("AdminGuardConfig");
export const USER_GUARD_CONFIG = new InjectionToken<MsalGuardConfiguration>("UserGuardConfig");

// Create specialized guard services
@Injectable()
export class AdminMsalGuard extends MsalGuard {
  constructor(
    @Inject(ADMIN_GUARD_CONFIG) config: MsalGuardConfiguration,
    // ... other dependencies
  ) {
    super(config /* ... other dependencies */);
  }
}

@Injectable()
export class UserMsalGuard extends MsalGuard {
  constructor(
    @Inject(USER_GUARD_CONFIG) config: MsalGuardConfiguration,
    // ... other dependencies
  ) {
    super(config /* ... other dependencies */);
  }
}

// Configure in module
@NgModule({
  providers: [
    {
      provide: ADMIN_GUARD_CONFIG,
      useValue: {
        interactionType: InteractionType.Redirect,
        authRequest: { scopes: ["user.read", "directory.read.all"] }
      }
    },
    {
      provide: USER_GUARD_CONFIG,
      useValue: {
        interactionType: InteractionType.Popup,
        authRequest: { scopes: ["user.read"] }
      }
    },
    AdminMsalGuard,
    UserMsalGuard
  ]
})
export class AppModule { }