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.
-
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 });
-
Find available events
The list of events available to MSAL can be found in the @azure/msal-browser event documentation. -
Unsubscribe
It is extremely important to unsubscribe. ImplementngOnDestroy()
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!
Updated 10 months ago