If you are planning to use the library in your Web Application to manage authentication with AWS Cognito UserPools Hosted UI, it is not fully clear how Amplify handles the authentication. open-source AWS Amplify JS This article shows you how to set up the Cognito UserPools and how it will integrate with an Angular Web Application. I will be considering AWS Cognito UserPools Code Grant flow. However, the steps are similar with Implicit flow also, except the session won’t get refreshed after id_token expires. JWT authentication flow Background: DevSecOps in Angular Applications Most development organizations are waking up to realize that security cannot be an afterthought in their development lifecycle. As part of the , dev teams are building security as an automated step in their delivery pipeline. shift towards DevSecOps When using AWS Amplify JS and similar open-source libraries for , it is extremely important to maintain these libraries up to date, keeping track of the ongoing release changes since these open source components lay the foundation for the security of the Web Application. security testing NPM now has a feature to perform an assessment of package dependencies for known security vulnerabilities. Since most of these libraries contain multiple third-party NPM dependencies, it's important to carry out audits for all of these. NPM security audit is capable of finding and fixing known vulnerabilities in dependencies which could potentially cause data loss, service outages, unauthorized access to sensitive information. For the ones NPM is not able to fix automatically, the audit report indicates them for manual developer intervention. security auditing Step 1: Install AWS Amplify in your Angular App If you are developing an Angular app, you can install an additional package aws-amplify-angular. This package contains an Angular module with a provider and components: $ npm install aws-amplify --save $ npm install aws-amplify-angular --save Step 2: Initialize Amplify Configurations You can initialize the Amplify Cognito UserPools and Cognito Federated Identities configuration in main.ts file. import Amplify from 'aws-amplify'; Amplify.configure({ Auth: { // other configurations... identityPoolId: 'us-east-1:xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', // REQUIRED - Amazon Cognito Identity Pool ID region: 'us-east-1', // REQUIRED - Amazon Cognito Region userPoolId: 'us-east-1_XYZPQRS', // OPTIONAL - Amazon Cognito User Pool ID userPoolWebClientId: 'xxxxxxxxxxxxxxxxxxxxxxxxx', // OPTIONAL - Amazon Cognito Web Client ID oauth: { domain: 'my-app-development.auth.us-east-1.amazoncognito.com', // Authorized scopes scope: ['email', 'openid'], // Callback URL redirectSignIn: 'http://localhost:4200/authenticated', // Sign out URL redirectSignOut: 'http://localhost:4200/logout', // 'code' for Authorization code grant, // 'token' for Implicit grant responseType: 'code', // optional, for Cognito hosted ui specified options options: { // Indicates if the data collection is enabled to support Cognito advanced security features. // By default, this flag is set to true. AdvancedSecurityDataCollectionFlag: true } }, }, }); Step 3: Initialize the Amplify Angular Resources You need to initialize the Angular Module and Service inside your app.module.ts file. import { AmplifyAngularModule, AmplifyService } from 'aws-amplify-angular'; @NgModule({ declarations: [ ... ], imports: [ BrowserModule, FormsModule, HttpModule, AmplifyAngularModule, ... ], providers: [ AmplifyService, ... ] }) Step 4: Create Required Routes You need to create multiple routes to implement the Cognito UserPools Hosted UI authentication process. Authenticated Route (e.g /authenticated) — This route where the HostedUI will redirect towards. Note: Make sure this route is not having any AuthGuard (More in next section) configured Home Route (e.g /home or /) — This route is where the user is redirected once the Cognito Token Handshake Completes. import { AuthGuardService as AuthGuard } from '../service/auth-guard.service'; const routes: Routes = [ { path: 'authenticated', component: AuthenticatedComponent}, { path: '', component: HomeComponent, canActivate: [AuthGuard]}, ]; Once Cognito Hosted UI redirects to the application, if you set up the above steps properly, Amplify internally communicates with Cognito UserPool token endpoint and retrieves the Tokens depending on the Grant Type and Scopes. Step 5: Create an AuthGuard to Protect Authenticated Routes Create an Angular Service implementing CanActivate method in Angular Router. import { Injectable } from '@angular/core'; import { Router, CanActivate, CanActivateChild, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; import { AmplifyService } from 'aws-amplify-angular'; @Injectable() export class AuthGuardService implements CanActivate { constructor() {} redirectToLogin() { const config = Amplify.Auth.configure(); const { domain, redirectSignIn, redirectSignOut, responseType } = config.oauth; const clientId = config.userPoolWebClientId; const url = 'https://' + domain + '/login?redirect_uri=' + redirectSignIn + '&response_type=' + responseType + '&client_id=' + clientId; // Launch hosted UI window.location.assign(url); } /* canActivate(): boolean { canActivate( next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> { return this.amplifyService.auth().currentSession().catch((error) => { this.redirectToLogin(); }); } } Step 6: Wait for Cognito Token Handshake at Authenticated Route Once the user is redirected to the authenticated route from Cognito UserPools Hosted UI, it is required to wait till Amplify handles the Cognito Token Handshake. Unfortunately for this, the Amplify Service State Change Observable is not properly working. Therefore it required using the Hub Middleware to Listen to the Event. import { Component, OnInit, TemplateRef } from '@angular/core'; import { Router, RouterModule, Routes } from '@angular/router'; import { Hub } from 'aws-amplify' @Component({ selector: 'app-authenticated', templateUrl: './authenticated.component.html', styleUrls: ['./authenticated.component.scss'] }) export class AuthenticatedComponent implements OnInit { constructor( private router: Router) { Hub.listen('auth', this, 'AuthCodeListner'); } onHubCapsule(capsule) { const { channel, payload } = capsule; if (channel === 'auth' && payload.event === 'signIn' ) { this.router.navigate(['']) } } ngOnInit() {} } Step 7: Use an HTTP Interceptor to send the Cognito ID Token for API Requests After authenticating properly, Amplify will store the Tokens in LocalStorage and you can access it using the amplifyService.auth().currentSession() method. Accessing the Tokens this.amplifyService.auth().currentSession().catch((error) => { this.redirectToLogin(); }); } Writing the Auth Interceptor For more details on writing, Auth Interceptor refer Angular Authentication: Using the Http Client and Http Interceptors. Step 8: Runn NPM Audit First of all upgrade NPM to the latest and then run the audit command, $ npm install npm@latest -g $ npm audit Npm audit automatically runs while installing packages with npm install. However, its useful to audit locally installed packages once in a while to identify recently found vulnerabilities. After running the audit command or if you see vulnerabilities after installing a new package in the npm audit report, run the npm audit fix subcommand to automatically install the compatible updates to fix identified vulnerable dependencies. $ npm audit fix At the time of this writing, when running npm audit for the AWS Amplify Angular Package, dependencies, npm audit found 30 vulnerabilities (7 low, 17 moderate, 6 high) in 4358 scanned packages where running `npm audit fix` is able to fix 29 of them.