Using OIDC and the Microsoft Authentication Library for Authenticating Against Azure AD

thumbprint security scan

INTRODUCTION

Most applications have the concerns of identity and access management. Identity Management covers the situations when an application needs to uniquely identify the person that is using it. The identification is represented typically by a User ID in the application. We need to verify that the person accessing the application is properly associated with the User ID. A login screen is provided for the person to confirm that they are, in fact, the person associated with the User ID for the application. The person enters the User ID and a secondary verification (usually a password) for confirmation. The process of an individual verifying that they are associated with the User ID is called Authentication. Two factor Authentication is also used for more security. 

We typically want to also limit what an individual can access when interacting with an application. The User ID is often associated with sets of permissions to access different parts of the application. The application will check these associated permissions and determine if the User ID is allowed access to various parts of the application. The application may have to see what roles and groups the user may be associated with.  The act of checking the appropriate access allowed for a User ID is referred to as Authorization. The creation and distribution of the permissions for an application is called Access Management.

It is unnecessary for developers to create custom code to perform the process of Authorization and Authentication. Building Authentication and Authorization with your own custom code is often complicated and error prone. Furthermore, many environments provide integrations and libraries to perform Authorization and Authentication without the need for the creation of any custom code. Azure Active Directory (Azure AD) is Microsoft’s cloud-based Identity and Access Management service. Azure AD stores the users’ identity and access permissions on a per organization and per application basis. Microsoft also provides an authentication library called Microsoft Authentication Library (MSAL). This library provides a standard way for you to access the services that Azure AD offers. These two technologies should be the starting point of any code development for Authorization and Authentication in an application that interacts with Azure.

Azure AD has several interfaces for Authentication and Authorization that use web-based standards. The focus of this blog will be the Open ID Connect (OIDC) interface for Authentication. To begin, we will provide some background information on Open ID Connect protocol before presenting an example of the protocol operation in Azure AD.

OIDC END POINTS

The OIDC standard is used to authenticate users for access to an application. OIDC is an extension of the OAuth2 web standard. OIDC provides standard URLs to query for particular authentication information. These URLs are referred to as API endpoints.

The end points provided by the API are the following:

1. The authorization endpoint (default URL path: /authorize): This endpoint is used for providing ID tokens and allow the user to authenticate. It also provides the authorization code for the authorization code flow with pkce. 

2. The token endpoint (default URL path: /token): This provides refresh and access tokens. It also verifies the authorization code for the authorization code flow with pkce.

3. The end sessions endpoint (default URL path: /logout): End the session associated with the given ID token.

4. The userinfo endpoint (default URL path: /userinfo): This is the endpoint that provides information about the currently logged in user.

5. The discovery endpoint (default URL path: /.well-known/openid-configuration): This endpoint provides information about the URLs for the other endpoints specified in OIDC.

AZURE AD OIDC ENDPOINTS

In Azure AD, each organization is represented by the concept of a tenant. The tenant is represented by an ID in Azure AD. All OIDC endpoints have at least a tenant ID associated with them. With this in mind, these endpoints in Azure AD correspond to the following endpoints in OIDC :

{your tenant id here}= represents the tenant ID of your organization. It should be of the format 00000000-0000-0000-0000-000000000000

1. The authorization endpoint: https://login.microsoftonline.com/{your tenant id here}/oauth2/v2.0/authorize

2. The token endpoint: https://login.microsoftonline.com/{your tenant id here}/oauth2/v2.0/token

3. The end sessions endpoint: https://login.microsoftonline.com/{your tenant id here}/oauth2/v2.0/logout

4. The userinfo endpoint: https://graph.microsoft.com/oidc/userinfo

5. The discovery endpoint: https://login.microsoftonline.com/{your tenant id here}/v2.0/.well-known/openid-configuration

OIDC FLOWS

There are several methods that are used for authentication in OIDC. These methods are called flows. They represent interactions between the clients below.

Resource Owner: The person or organization that is identified with the particular item you are trying to access. (In Azure AD, a tenant)

Resource Server: The server on which the item resides. This could be an API or a file. (In Azure AD, a good example is an API)

Client Server: The server that is trying to access the item on the resource server to perform some type of operation. (In Azure AD, usually a third-party web server)

Authorization Server: The server that authenticates and authorizes access to items on the resource server. (This is OIDC endpoints in Azure AD)

User Agent: The application that a user uses to access items on the resource server. (In Azure AD, usually a web browser but could be other clients like a smart phone)

This section briefly describes each of the available OIDC flows. 

1. Implicit Grant Flow – The user agent requests the ID token and accesses the token at the same time. There is no allowance for refreshing of expressed tokens without using client credentials to authenticate against an endpoint. This can be very problematic. For this reason, implicit grant flow is generally deprecated for web browsers. It is also disabled in MSAL 2.0.

2. Authorization Code Flow – This flow involves the user agent, the client server, the authentication server, and the resource server. The user agent is given a one-time authorization code that is passed to the client server for redemption of an access token. The access token is stored on the client server once received. The access token is never available to the user agent. 

3. Authorization Code Flow with PKCE (Proof Key for Code Exchange) – This flow involves the user agent, the authentication server, and the resource server. The user agent is given a one-time authorization code and issues a challenge code that is passed to the authorization server. This results in the user agent being given an access token once the authentication server has verified the user.

4. Client Credential Flow – This flow involves the client server, the authentication server, and the resource server. It is usually considered secure since it does not involve actual interaction from the user agent. For this reason, the authentication and authorization between the authorization server and the client server tend to use client certificates or user secrets for authentication, along with information about the items on the resource server for which the client server has authorization. 

5. Device Code – This occurs when the initial user agent is input restrained. The user is then prompted to use a web browser to authenticate the input restrained user agent.

6. Resource Owner Password Flow – This flow involves the client server and the authentication server. A username and password are passed to the authentication server and then the authentication server passes confirmation back. This flow has been deprecated since it is very easy to expose the username and password.

CODE EXAMPLE FOR MSAL FOR ANGULAR

The Microsoft Authentication Library (MSAL) is provided for a number of platforms. 

The list of libraries and platforms are provided here: 

https://docs.microsoft.com/en-us/azure/active-directory/develop/reference-v2-libraries

The code discussed below is from the following MSAL example that uses Angular to provide authentication:

https://github.com/Azure-Samples/ms-identity-javascript-angular-spa

There are several issues to be aware of about the MSAL Angular library. The MSAL library uses the Authorization Code Flow with PKCE (Proof Key for Code Exchange) for the default OIDC flow.

There are 3 login scenarios that are allowed for the MSAL Angular library:

Popup – The login page hosted by Azure AD will pop up in a separate window and require entry of the user’s login credentials.

Redirect – The web application will redirect to the login page hosted by Azure AD.

Silent – The web application will attempt to refresh its credentials with no user interaction and fail if there are no available credentials.

The first two login scenarios are only allowed on the initial login. The project is initially defaulted to the redirect option. You will need to perform a few steps before you can run the code example successfully.

SETUP STEPS FOR CODE EXAMPLE

1. Register the application under the tenant in the Azure portal. (Note: please make sure that one saves the Tenant ID and Application ID when one registers the application in the portal)

2. Change the information in the ms-identity-javascript-angular-spa\src\app\app.module.ts file

3. Export

function MSALInstanceFactory(): IPublicClientApplication {

return new PublicClientApplication({

auth: {

      clientId: 'Enter_the_Application_Id_Here',

      authority: 'Enter_the_Cloud_Instance_Id_HereEnter_the_Tenant_Info_Here',

      redirectUri: 'Enter_the_Redirect_Uri_Here' 

      },

a. Set redirectUri to {angular application url}

b. Set authority to https://login.microsoftonline.com/{tenant id}. 

c. Set clientId to {application id}.

4. Change the settings in the ms-identity-javascript-angular-spa\src\app\app-routing.module.ts file

            From 

            NgModule({

          imports: [RouterModule.forRoot(routes, {

           useHash: true, // set this line to false

           // Don't perform initial navigation in iframes

           initialNavigation: !isIframe ? 'enabled' : 'disabled'

     })],

     exports: [RouterModule]

     })

to 

            NgModule({

          imports: [RouterModule.forRoot(routes, {

           useHash: false,

           // Don't perform initial navigation in iframes

           initialNavigation: !isIframe ? 'enabled' : 'disabled'

     })],

     exports: [RouterModule]

     })

The redirect uri can be set to http://localhost:4200 for a standard Angular application or to the url for the Angular application. Be sure to set the redirect uri to the same value in the Azure portal for the application. The Tenant ID and Application ID will be the Tenant ID and Application ID received when registering the application in the Azure portal in step 1. 

The project has an issue with the popup redirection that can be fixed by the code adjustment in step 3. This change will allow the login page hosted by Azure AD to popup in another window properly. 

Once this is completed, one will be able to authenticate the app using OIDC.

RUNNING CODE EXAMPLE

1. Switch to the ms-identity-javascript-angular-spa directory

     cd ms-identity-javascript-angular-spa

2. Start the angular development server

     run npm start 

3.   Click the login button on the page

4.   Provide your Azure AD credentials

5.   User logged in now

The running of the example code is very easy. There is a lot going on behind the scenes. To get a better understanding of how the MSAL library performs the complete process, we will outline the mechanism at a high level from when you click the login button to when the login has successfully been completed.

CODE FLOW WITH AZURE AD 

1.   User clicks login button

2.   Angular application calls the loginPopup() or loginRedirect() on the msal authorization service,  the call to loginPopup or loginRedirect is dependent on the type of login method specified.

3.   When the above method is called, the MSAL library issues an authorization message to the Azure AD authorize endpoint.  (https://login.microsoftonline.com/{tenant id}/oauth2/v2.0/authorize) 

4.   Azure AD presents a login screen for the user to authenticate. Azure AD knows what application is being used by the authorization message passed in from the Angular code.

5.   If the user provides the correct authorization information, Azure AD passes an authorization code back to the web browser. 

6.   The web browser now requests an access token by sending the authorization code in step 5 to the token endpoint. (https://login.microsoftonline.com/{tenant id}/oauth2/v2.0/token)

7.   The web browser receives an access token back from the token end point

8.   User is logged in

9.   Access token is stored in the web browsers local storage

PKCE FLOW

There is also a PKCE (Proof Key for Code Exchange) process happening along with the Authorization process. This is an additional security measure to prevent something else on the web from pretending to be the web browser. This involves a string called code verifier. This is equivalent to a one-time password.

The web browser generates this string. The web browser then hashes the code verifier into another string called the code challenge. It passes all this information to Azure AD with the authorization message in Step 3. The web browser sends the code verifier string to Azure AD in Step 5. The code verifier is used to verify that the web browser is the original web browser that made the request by Azure AD.

CONCLUSION

We hope to have provided you with an overall basic understanding of how to use the OIDC interface of Azure AD. Azure AD is a way to provide Authentication and Authorization in the cloud and on the web. With this information, you should be able to import MSAL into your beginning web project and start providing Authentication and Authorization through Azure AD without the need for writing any additional code for your project. Check our blogs for additional examples of using standards such as OAuth2 and OIDC.