Angular Applications

This page will help you authenticate your Angular application.

πŸ“˜

External Applications

This authentication guide applies to applications hosted outside the congacloud.io domain. Authentication for congacloud.io hosted apps are handled internally by the platform and do not use the authorization code flow described in this document.

About

This guide will walk you through setting up the OAuth 2.0 authorization code flow with PKCE to connect browser-based applications with Conga API services. Your app will be able to get tokens that you can use with the APIs listed in the API reference.

The @azure/msal-angular and @azure/msal-react packages described by the code in this guide wrap the @azure/msal-browser package and use it as a peer dependency to enable authentication in single-page web applications without backend servers. This version of the library uses the OAuth 2.0 Authorization Code Flow with PKCE.

Prerequisites

This guide assumes you are building a single-page application (SPA) using the Angular Framework and you have obtained a client ID from the Conga authentication service. Your redirect URI must be registered with the application.

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

In this document:

Include and initialize the MSAL module in your app module

Import MsalModule into app.module.ts. To initialize MsalModule you must pass your application's clientId, which you can get from the Conga Authentication Service.

import { NgModule } from '@angular/core';
import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';
import { AppComponent } from './app.component';
import { MsalModule, MsalService, MsalGuard, MsalInterceptor, MsalBroadcastService, MsalRedirectComponent } from "@azure/msal-angular";
import { PublicClientApplication, InteractionType, BrowserCacheLocation } from "@azure/msal-browser";


@NgModule({
    imports: [
        MsalModule.forRoot( new PublicClientApplication({ // MSAL Configuration
            auth: {
                clientId: "***Your client ID***",
                authority: "***Your Authority URL***",
                redirectUri:  window.location.origin + window.location.pathname,
                knownAuthorities: ['***Your Authority URL***'],
                protocolMode: ProtocolMode.OIDC
            },
            cache: {
                cacheLocation : BrowserCacheLocation.LocalStorage,
                storeAuthStateInCookie: true, // set to true for IE 11
            },
            system: {
                loggerOptions: {
                    loggerCallback: () => {},
                    piiLoggingEnabled: false
                }
            }
        }), {
            interactionType: InteractionType.Redirect, // MSAL Guard Configuration
        }, {
            interactionType: InteractionType.Redirect, // MSAL Interceptor Configuration
        })
    ],
    providers: [
        {
            provide: HTTP_INTERCEPTORS,
            useClass: MsalInterceptor,
            multi: true
        },
        MsalService,
        MsalGuard,
        MsalBroadcastService
    ],
    bootstrap: [AppComponent, MsalRedirectComponent]
})
export class AppModule {}

Secure the routes in your application

You can add authentication to secure specific routes in your application by just adding canActivate: [MsalGuard] to your route definition. It can be added at the parent or child routes. When a user visits these routes, the library will prompt the user to authenticate.

See the MsalGuard doc for more details on configuration and considerations, including using additional interfaces.

See this example of a route defined with the MsalGuard:

  {
    path: 'profile',
    component: ProfileComponent,
    canActivate: [MsalGuard]
  },

Get tokens for Web API calls

@azure/msal-angular allows you to add an Http interceptor (MsalInterceptor) in your app.module.ts as follows. MsalInterceptor obtains tokens and adds them to your HTTP requests in API calls based on the protected resource map (protectedResourceMap). See the MsalInterceptor doc for more details on configuration and use.

import { NgModule } from '@angular/core';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { AppComponent } from './app.component';
import { MsalModule, MsalService, MsalGuard, MsalInterceptor, MsalBroadcastService, MsalRedirectComponent } from "@azure/msal-angular";
import { PublicClientApplication, InteractionType, BrowserCacheLocation } from "@azure/msal-browser";

@NgModule({
    imports: [
        MsalModule.forRoot( new PublicClientApplication({ // MSAL Configuration
            auth: {
               clientId: "Your client ID",
                authority: "***Your Authority URL***",
                redirectUri:  window.location.origin + window.location.pathname,
                knownAuthorities: ['***Your Authority URL***'],
                protocolMode: ProtocolMode.OIDC
            },
            cache: {
                cacheLocation : BrowserCacheLocation.LocalStorage,
                storeAuthStateInCookie: true, // set to true for IE 11
            },
            system: {
                loggerOptions: {
                    loggerCallback: () => {},
                    piiLoggingEnabled: false
                }
            }
        }), {
            interactionType: InteractionType.Redirect, // MSAL Guard Configuration
        }, {
            interactionType: InteractionType.Redirect, // MSAL Interceptor Configuration
            protectedResourceMap: new Map([
                ['***Your API Domain***', ['openid', 'offline_access']]
            ])
        })
    ],
    providers: [
        {
            provide: HTTP_INTERCEPTORS,
            useClass: MsalInterceptor,
            multi: true
        },
        MsalService,
        MsalGuard,
        MsalBroadcastService
    ],
    bootstrap: [AppComponent, MsalRedirectComponent]
})
export class AppModule {}

Using MsalInterceptor is optional. You may want to acquire tokens explicitly using the acquireToken APIs instead.

Please note that the MSAL Interceptor is provided for your convenience and may not fit all use cases. We encourage you to write your own interceptor if you have specific needs that are not addressed by MsalInterceptor.

Event Subscription

MSAL provides an event system that emits events related to Auth and MSAL, and can be subscribed to as shown below. To use events, add the MsalBroadcastService to the constructor in your component/service.

  1. Subscribe to events:

    import { EventMessage, EventType } from '@azure/msal-browser';
    
    this.msalBroadcastService.msalSubject$
        .pipe(
            filter((msg: EventMessage) => msg.eventType === EventType.LOGIN_SUCCESS)
        )
        .subscribe((result) => {
            // do something here
        });
    
  1. Find available events
    The list of events available to MSAL can be found in the @azure/msal-browser event documentation.

  2. Unsubscribe
    It is extremely important to unsubscribe. Implement ngOnDestroy() in your component and unsubscribe.

    private readonly _destroying$ = new Subject<void>();
    
    this.msalBroadcastService.msalSubject$
        .pipe(
            filter((msg: EventMessage) => msg.eventType === EventType.LOGIN_SUCCESS),
            takeUntil(this._destroying$)
        )
        .subscribe((result) => {
            this.checkAccount();
        });
    
    ngOnDestroy(): void {
        this._destroying$.next(null);
        this._destroying$.complete();
    }
    

Next Steps

You are ready to use Conga public APIs!