Microsoft Azure uses an identity-as-a-service mode that relies on industry standard protocols to support authentication and authorization into various types of cloud-based services. These protocols are OIDC (OpenID Connect) and OAuth 2.0. While these protocols and services are standards-compliant, there can be subtle differences between various implementations of them. OpenID Connect (OIDC) is an authentication protocol that’s built on OAuth 2.0 and can be used to securely sign a user in to an application. OAuth2 is a protocol used for authorization in to protected resources. It is possible to have both protocols to work together to get authorization to access resources that the user owns and as such the terminology and flow are similar between the two. Authentication wise, OIDC is an alternative to the SAML protocol in that both deal with authentication. SAML authentication is commonly used with identity providers such as Active Directory Federation Services (ADFS) federated to Azure AD and is therefore frequently used in enterprise applications. OpenID Connect is commonly used for apps that are purely in the cloud, such as mobile apps, web sites, and web APIs. The Microsoft identity platform supports authentication for different kinds of modern application architectures. By using the authentication libraries for the Microsoft identity platform or any other libraries that are Azure SSO friendly, applications can authenticate identities and acquire tokens to access protected APIs.
In nearly all OAuth 2.0 and OpenID Connect flows, there are four parties involved in the exchange:
- The Authorization Server is the Microsoft identity platform and is responsible for ensuring the user’s identity, granting and revoking access to resources, and the issuing of tokens. The authorization server is also known as the identity provider – it securely handles anything to do with the user’s information, their access, and the trust relationships between parties in a flow.
- The Resource Owner is typically the end user. It’s the party that owns the data and has the power to allow clients to access that data or resource.
- The OAuth Client is your app, identified by its application ID. The OAuth client is usually the party that the end user interacts with, and it requests tokens from the authorization server. The client must be granted permission to access the resource by the resource owner. In SAML schemes this is is known as the SP side.
- The Resource Server is where the resource or data resides. It trusts the Authorization Server to securely authenticate and authorize the OAuth Client, and uses Bearer access tokens to ensure that access to a resource can be granted.
App Registration
For an identity provider to know that a user has access to a particular app, both the user and the application must be registered with the identity provider. When you register your application with Azure AD, you are providing an identity configuration for your application that allows it to integrate with the Microsoft identity platform. Registering the app also allows you to:
- Customize the branding of your application in the sign-in dialog. This is important because this is the first experience a user will have with your app.
- Decide if you want to let users sign in only if they belong to your organization (single tenant application) or allow users to sign in using any work or school account (multi-tenant application).
- Request scope permissions. For example, you can request the “user.read” scope, which grants permission to read the profile of the signed-in user.
- Define scopes that define access to your web API. Typically, when an app wants to access your API, it will need to request permissions to the scopes you define.
- Share a secret with Microsoft identity platform that proves the app’s identity. This is relevant in the case where the app is a confidential client application. A confidential client application is an application that can hold credentials securely. They require a trusted back-end server to store the credentials.
Once registered, the application will be given a unique identifier that the app shares with the identity platform when it requests tokens. If the app is a confidential client application, it will also share the secret or the public key depending on whether certificates or secrets were used in the app registration.
The app registration process requires a few values to register your app:
- An Application ID that uniquely identifies your app (generated by Azure)
- A Redirect URI (optional) that can be used to direct responses back to your app. This is similar to the ACS URI in SAML schemes.
- A few other scenario-specific values depending on the complexity of the required access.
Endpoints
Once registered, the app can communicate with the Microsoft identity platform by sending requests to the authorization server endpoint via these typical URLs:
https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize
https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token
Where the {tenant} can take one of four different values:
Value | Description |
common | Allows users with both personal Microsoft accounts and work/school accounts from Azure AD to sign into the application. |
organizations | Allows only users with work/school accounts from Azure AD to sign into the application. |
consumers | Allows only users with personal Microsoft accounts (MSA) to sign into the application. |
8eaef023-2b34-4da1-9baa-8bc8c9d6a490 or contoso.onmicrosoft.com | Allows only users with work/school accounts from a particular Azure AD tenant to sign into the application. Either the friendly domain name of the Azure AD tenant or the tenant’s GUID identifier can be used. |
Typically, during the app registration process the above value will be set to the ‘McMaster University users’ tenant value setting as there are no other organizations linked.
Protected Resources vs. Client Applications
Authentication scenarios via OIDC/OAuth2 involve two activities:
- Acquiring security tokens for a protected web API: We recommend that you use the Microsoft Authentication Library (MSAL), developed and supported by Microsoft but any other scripting scenario could work as well.
- Protecting a web API or a web app: One challenge of protecting these resources is validating the security token. On some platforms, Microsoft offers middleware libraries.
Tokens
OAuth 2.0 and OpenID Connect make extensive use of bearer tokens, generally represented as JWT (JSON Web Tokens). A bearer token is a lightweight security token that grants the “bearer” access to a protected resource. In this sense, the “bearer” is anyone that gets a copy of the token. Though a party must first authenticate with the Microsoft identity platform to receive the bearer token, if the required steps are not taken to secure the token in transmission and storage, it can be intercepted and used by an unintended party. While some security tokens have a built-in mechanism for preventing unauthorized parties from using them, bearer tokens do not have this mechanism and must be transported in a secure channel using transport layer security (HTTPS). If a bearer token is transmitted in the clear, a malicious party can use a man-in-the-middle attack to acquire the token and use it for unauthorized access to a protected resource. The same security principles apply when storing or caching bearer tokens for later use. Always ensure that your app transmits and stores bearer tokens in a secure manner.
There are 3 types of tokens used in OAuth 2.0 / OIDC:
- Access tokens – tokens that a resource server receives from a client, containing permissions the client has been granted.
- ID tokens – tokens that a client receives from the authorization server, used to sign in a user and get basic information about them.
- Refresh tokens – used by a client to get new access and ID tokens over time. These are opaque strings, and are only understandable by the authorization server.
An access token is a security token that is issued by an authorization server as part of an OAuth 2.0 flow. It contains information about the user and the app for which the token is intended and can be used to access web APIs and other protected resources. Access tokens are only valid for a short period of time, so authorization servers will sometimes issue a refresh token at the same time the access token is issued. The client application can then exchange this refresh token for a new access token when needed. ID tokens are sent to the client application as part of an OpenID Connect flow. They can be sent along side or instead of an access token, and are used by the client to authenticate the user.
Validating security tokens
It is up to the app for which the token was generated, the web app that signed-in the user, or the web API being called, to validate the token. The token is signed by the Security Token Server (STS) with a private key. The STS publishes the corresponding public key. To validate a token, the app verifies the signature by using the STS public key to validate that the signature was created using the private key. Tokens are only valid for a limited amount of time. Usually the STS provides a pair of tokens:
- An access token to access the application or protected resource, and
- A refresh token used to refresh the access token when the access token is close to expiring.
Access tokens are passed to a web API as the bearer token in the Authorization header. An app can provide a refresh token to the STS, and if the user access to the app wasn’t revoked, it will get back a new access token and a new refresh token.
JSON Web Tokens (JWTs) and Claims
The Microsoft identity platform implements security tokens as JSON Web Tokens (JWTs) that contain claims. Since JWTs are used as security tokens, this form of authentication is sometimes called JWT authentication.
A claim provides assertions about one entity, such as a client application or resource owner, to another entity, such as a resource server. A claim may also be referred to as a JWT claim or JSON Web Token claim. Claims are name/value pairs that relay facts about the token subject. For example, a claim may contain facts about the security principal that was authenticated by the authorization server. The claims present in a given token depend on many things, including the type of token, the type of credential used to authenticate the subject, the application configuration, and so on.
Applications can use claims for various tasks such as:
- Validating the token
- Identifying the token subject’s tenant
- Displaying user information
- Determining the subject’s authorization
A claim consists of key-value pairs that provide information such as the:
- Security Token Server that generated the token
- Date when the token was generated
- Subject (such as the user–except for daemons)
- Audience, which is the app for which the token was generated
- App (the client) that asked for the token. In the case of web apps, this may be the same as the audience
How Each Flow Emits Tokens and Codes
Depending on how your client application is built, it can use one (or several) of the authentication flows supported by Microsoft identity platform. These flows can produce a variety of tokens (ID tokens, refresh tokens, access tokens) as well as authorization codes, and require different tokens to make them work. This chart provides an overview of these:
FLOW | REQUIRES | ID TOKEN | ACCESS TOKEN | REFRESH TOKEN | AUTHORIZATION CODE |
Authorization Code Flow | X | X | X | X | |
Implicit flow | X | X | |||
Hybrid OIDC flow | X | X | |||
Refresh token redemption | refresh token | X | X | X | |
On-behalf-of flow | access token | X | X | X | |
Client credentials | X (app-only) |
Tokens issued via the implicit mode have a length limitation due to being passed back to the browser via the URL (where response_mode is query or fragment). Some browsers have a limit on the size of the URL that can be put in the browser bar and fail when it is too long. Thus, these tokens do not have groups or wids claims.
Tokens and Sign-ins With Users or Without users
Most authentication scenarios acquire tokens on behalf of signed-in users but in some cases, it is possible to obtain tokens without any user sign-in. Security tokens can be acquired by multiple types of applications. These applications tend to be separated into the following three categories. Each is generally used with different libraries and objects.
- Single-page applications: Also known as SPAs, these are web apps in which tokens are acquired by a JavaScript or TypeScript app running in the browser. Many modern apps have a single-page application at the front end that is primarily written in JavaScript (other scripting technologies also can accomplish the same). The application often uses a framework like Angular, React, Node or Vue. js is the only Microsoft Authentication Library that supports single-page applications. This Category is the most common and most widely adopted for authentication/authorization scenarios.
- Public client applications: Apps in this category, like the following types, always sign in users:
- Desktop apps that call web APIs on behalf of signed-in users
- Mobile apps
- Apps running on devices that don’t have a browser, like those running on IoT
- Confidential client applications: Apps in this category include:
- Web apps that call a web API
- Web APIs that call a web API
- Daemon apps, even when implemented as a console service like a Linux daemon or a Windows service
The following illustrates the common authentication/authorization scenarios supported by the Microsoft Identity Platform:
Sign-in audience
The available authentication flows differ depending on the sign-in audience. Some flows are available only for work or school accounts. Others are available both for work or school accounts and for personal Microsoft accounts. In the case of McMaster University this applies to work accounts for employees and school accounts for students and essentially all follow the same convention in terms of authenticating entities via an identity that uses this format: “uniqueID@organization.ca”
Authorization code flow vs. implicit flow
For most of the history of OAuth 2.0, the implicit flow was the recommended way to build single-page apps. But with the removal of third-party cookies and greater attention paid to security concerns around the implicit flow, the recommended method nowadays is to use authorization code flow for single-page apps. The Microsoft identity platform offers two grant types for applications:
Implicit flow (MSAL.js v.1.x)
Authorization code flow (with PKCE) (MSAL.js v.2.0)
The following diagram illustrates the library architecture around these flows:
For further information on how to build and deploy apps via any of these methods read here.