Quote of the Day

more Quotes

Categories

Buy me a coffee

  • Home>
  • security>

OIDC implicit flow in angular with MSAL for angular, Microsoft Identity Platform (v2.0) and Azure AD.

In this post, I share my experience about doing OpenID Connect (OIDC) implicit flow using Microsoft Authentication library (MSAL) for Angular, Microsoft Identity Platform (v2.0), and Azure AD. This post is part of the blog post series in which I cover implementing OIDC flows to protect as system that consists of an angular front-end application and asp.net core web apis. In the previous post, I give a high level overview of the technologies involved in protecting such a system.

It’s all about standard and protocol

The sign in flow follows OpenID Connect (OIDC) implicit flow, which is suitable for a public client.

A public client basically means an application which is not able to hide the application’s identity (client id and secret). An angular or a javascript based frontend application is a public client because a user can debug the source codes as well as inspect the traffics through the browser. The other type of client application is Confidential Client, which refers to an application that is able to keep the client id and secret safe. An example of a confidential client is a web api application residing on a private server. The web api is able to keep the client id and secret secure in a sense that end users are not able to see source codes or access the server.

OIDC is a protocol that extends from OAuth2. OAuth2 is a protocol for client applications to obtain an access token which represents an authorization to access specific resources. OAuth2 does not state how authentication should occur, as it is an authorization, not authentication protocol. If you want to learn more, checkout my post in which I list some of the reasons why OAuth2 is not an authentication protocol. OIDC comes along and defines the flows to obtain not just an access token, but also an id token which represents a user’s identity. The implicit flow is appropriate for a public client such as an angular front end application. For more info about other flows and the differences between them, checkout this concise post. Suffice it to say the authorization flow is for confidential clients and implicit flow is for public clients. The authorization flow requires an extra step during which the client application authenticates itself using the client’s credentials (client id and secret/certificate) against the authorization server to obtain an authorization code which the client then uses to obtain tokens from the token endpoint. With the implicit flow, the client requests the tokens directly from the authorization endpoint, without having to obtain an authorization code.

Here is the description of OIDC from Wikipedia:

OpenID Connect is a simple identity layer on top of the OAuth 2.0 protocol, which allows computing clients to verify the identity of an end-user based on the authentication performed by an authorization server, as well as to obtain basic profile information about the end-user in an interoperable and REST-like manner. In technical terms, OpenID Connect specifies a RESTful HTTP API, using JSON as a data format.
OpenID Connect allows a range of clients, including Web-based, mobile, and JavaScript clients, to request and receive information about authenticated sessions and end-users. The specification suite is extensible, supporting optional features such as encryption of identity data, discovery of OpenID Providers, and session management.[1]

Wikipedia

MSAL for angular

MSAL for angular is a wrapper library, based on MSAL for Javascript. The library implements OIDC implicit flow. As such, it is suitable for using to interact with an authorization server to authenticate the user and obtain tokens.

I find the library intuitive to use as it abstracts away much of the complexity in implementing the implicit flow. At the high level, you configure the library by providing the parameters such as redirect url, authorization endpoint, logging etc … You then provide business logics by subscribing to the four events (login success, login failure, acquire token success, acquire token failure) so the library knows what to do when those events occur. The library handles the interactions with the authorization server to authenticate the user, obtain tokens, cache user info and tokens in browser storage, include bearer tokens when making requests to protected endpoints, and protect the routes in your app. For examples of how to setup and use the library, check out the documentation.

Although the library is intuitive in terms of usage; however, it is still in preview, and there are known issues. For instance, as of this writing, it currently supports angular 2 to 5, although angular 8 is already out. Also, currently the library does not work in IE 7.

As it is of often the case with using a new library, expect to face issues when using MSAL for angular. Be sure to check out the known issues page when considering using the library in your project.

I strongly suggest you checkout the issues page before using the library.

Microsoft Identity Platform

If you want to authenticate a user against Azure AD, you basically can choose between two authorization endpoints: Azure AD developer platform (v1.0 endpoint) or Microsoft Identity Platform (v2.0 endpoint). In the context of OIDC, both platforms act as authorization servers and identity providers. In other words, they handle ensuring the user’s identity, issuing tokens, granting and revoking accesses.

Microsoft Identity Platform is the successor of Azure AD developer platform. The main advantages v2.0 endpoint has over its predecessor are basically support for all types of Microsoft accounts (school, work/business and personal), ability to request consent incrementally, and fine grain access via scopes instead of resources. For more details about the advantages of v2.0 endpoint over v1.0 endpoint, checkout the documentation. If you are developing a new application, chances are you would want to use v2.0 endpoint instead of the older one. However, v2.0 endpoint has some limitations, which you can read more about here.

Microsoft Identity Platform is OIDC compliant, so technically it should work with any OIDC compliant client libraries. Although I am currently using MSAL for angular to interact with Microsoft Identity Platform v2.0 endpoint and discussing about the library in this post, I have experienced issues relating to IE11 support and sign in via redirect. I am switching to using oidc-client library now and likely do a blog post on it to share my experiences.

Authenticate the user and obtain id token

The below diagram more or less depicts what happens during an implicit flow to authenticate an user and obtain an id token. For this example, the user is from an organization which has enabled federation to allow its’ users to authenticate against azure ad using their on-premise passwords. To learn more, checkout the document on Azure AD Connect and federation.

OIDC implicit flow with MSAL for angular, Microsoft Identity Platform v2.0 endpoint, and Azure AD

In the context of OIDC, the client is the angular app, the principal is the user, and the authorization server is Microsoft Identity Platform v2.0 endpoint.

Below I list the steps and include some of the requests, responses I observe during an OIDC implicit flow to give you some ideas about the interactions between the different players: the user, MSAL for angular, Microsoft Identity Platform v2.0, Azure AD and active directory on premise. I have modified and removed some information for simplicity and privacy.

Step 1: When the user clicks sign in from the angular application, the app sends a request to the authorization endpoint, which is Microsoft Identity Platform v2.0 endpoint.

https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?response_type=id_token&scope=openid%20profile&client_id={client_id}&redirect_uri={redirect_uri}&client_info=1&x-client-SKU=MSAL.JS&x-client-Ver=0.2.1&client-request-id={clientRequestId}&prompt=select_account&response_mode=fragment

You can read about the parameters in the above sample request from the document.

Step 2: MSAL library sends the user to the authorization endpoint , which is Microsoft Identity Platform v2.0 endpoint.

Step 3: If the user has previously signed in using one or more Microsoft’s account, the user can pick an account to login. Otherwise, the user enters the email to login. In the above request, MSAL sets the prompt parameter to “select_account” for an interactive sign in request.

Step 4: Microsoft Identity Platform identify the type of account based on the email. Below show a simplified post request from Microsoft Identity Platform to determine the type of account:

POST https://login.microsoftonline.com/common/GetCredentialType?
{"username":"jdoe@xyz.org","isOtherIdpSupported":false,"checkPhones":false,"isRemoteNGCSupported":true,"isCookieBannerShown":false,"isFidoSupported":false,"originalRequest":"rqI..","country":"US","forceotclogin":false,"isExternalFederationDisallowed":false,"isRemoteConnectSupported":false,"flowToken":"..."}

Here is a sample response. Notice the url to federate to the on-premise active directory for authentication.

{"Username":"johndow@xyz.org","Display":"johndow@xyz.org","IfExistsResult":0,"ThrottleStatus":1,"Credentials":{"PrefCredential":4,"HasPassword":true,"RemoteNgcParams":null,"FidoParams":null,"SasParams":null,"FederationRedirectUrl":"https://adfs.xyz.org/adfs/ls/?client-request-id=7a615c85-7da5-43f3-a348-****&username=jdoe%40xyz.org&wa=wsignin1.0&..."}

Step 5: The user enters the on-premise password to authenticate.

Step 6: Upon successful authentication, browser makes a post request to Microsoft Identity Platform with information of the authenticated user.

POST https://login.microsoftonline.com/login.srf HTTP/1.1
Host: login.microsoftonline.com
... (some headers omitted for brevity)
Referer: https://adfs.xyz.org/adfs/ls/?client-request-id=7a336dbf-6fec-4f10....=&username=jdoe%xyz.org&mkt=&lc=
Cookie: ESTSSSOTILES=1; AADSSOTILES=1; x-ms-gateway-slice=prod; stsservicecookie=ests; AADSSO=NA|NoExtension; ESTSSC=00; esctx=AQABAAA...CCState=Q2tz...wa=wsignin1.0&wresult=%3Ct%3ARequestSecurityTokenResponse+xmlns%3At%3D%22http%3A%2F%2Fschemas.xmlsoap.org%2Fws%2F2...Expires%3E%3C%2Ft%3ALifetime%3E%3Cwsp%3AAppliesTo+xmlns%3Awsp%3D%22..

Step 7: Microsoft Identity Platform replies with a 302, includes the id token in the redirect url, and set-cookie headers.

HTTP/1.1 302 Found
... (some headers omitted for brevity) 
Set-Cookie: ESTSWCTXFLOWTOKEN=; expires=Fri, 12-Jul-2019 07:03:30 GMT; path=/; secure; HttpOnly
Set-Cookie: AADSSO=; expires=Fri, 12-Jul-2019 07:03:30 GMT; path=/; secure; HttpOnly
Set-Cookie: ESTSAUTHPERSISTENT=...; expires=Mon, 12-Aug-2019 07:03:30 GMT; path=/; secure; HttpOnly
Set-Cookie: CCState=...; domain=.login.microsoftonline.com; expires=Mon, 12-Aug-2019 06:58:30 GMT; path=/; secure; HttpOnly
Set-Cookie: SignInStateCookie=...; path=/; secure; HttpOnly
Set-Cookie: fpc=...; expires=Mon, 12-Aug-2019 07:03:30 GMT; path=/; secure; HttpOnly
Set-Cookie: x-ms-gateway-slice=prod; path=/; secure; HttpOnly
Set-Cookie: stsservicecookie=ests; path=/; secure; HttpOnly
Date: Sat, 13 Jul 2019 07:03:30 GMT
Content-Length: 1571
<html><head><title>Object moved</title></head><body>
<h2>Object moved to <a href="https://{appUrl}#id_token={idToken}">here</a>.</h2>
</body></html>

Step 8: Browser sets cookies per the header and redirects the user back to the app.

Step 9: MSAL caches the token in browser storage.

At this point, the user is logged in. However, the id token only represents the authentication part. Before making a request to a protected endpoint, you still need to obtain an access token. Msal for angular has the MsalInterceptor class which you can use to automatically get an access token and include it in the header of a HTTP request to a protected resource.

Resources

OpenID Connect

OpenID Connect Flows

Public Client and Confidential Client applications

Microsoft Authentication Library for Angular Preview

Microsoft identity platform and OpenID Connect protocol

Evolution of Microsoft identity platform

Why update to Microsoft identity platform (v2.0)?

Diagrams of All The OpenID Connect Flows

Permissions and consent in the Microsoft identity platform endpoint

No comments yet