I was assisting a colleague recently with a Cisco ISE integration into Microsoft’s Entra ID. They had set up the permissions, granted consent, but it still wasn’t working, and they were stumped. I jumped on a call with them and the issue was quickly apparent - they’d used delegated permissions instead of application permissions. This got me thinking… this is probably a good topic to write an article on.

When I was initially learning Azure many years ago, I found the areas of application registration, enterprise applications and service principals very confusing. To this day, I still find elements of it confusing! In the process of writing the initial version of this blog post, I realised myself that there were some areas that I’d become rusty on and wasn’t articulating them clearly, nor did I provide enough background context. I figured I had two options:

  1. Embrace a bit of smoke and mirrors, and hope no one noticed.
  2. Take the time to go back to basics, step through it all in a multi-part post and come out of it a wiser man 😄!

You’ll be glad to hear I opted for option two. So, this will be the first in a number of posts that are going to focus on applications, authentication/authorisation and how these all glue together when using Entra ID.


Authentication

Authentication is the process of verifying the identity of a user or system. It is a fundamental aspect of security in any system, as it ensures that only authorised users or systems can access the resources.

When developing an application, the chances are you’d like to know who your users are! You probably also want them to prove their identity before giving them access to parts of your application. Generally speaking, you’ve two main approaches for implementing authentication, and which you choose likely depends on how large and complex your application is, and what tasks you fancy managing.

Local authentication database

Easy to understand and potentially simpler to implement (depending on your viewpoint), but means you need to manage salting and encryption of passwords and all the security challenges that go with it. You have usernames and passwords (well, hopefully salted and hashed passwords!) stored in some sort of database with appropriate protection.

Users end up having to remember lots of passwords, which isn’t great. And this likely leads to password re-use (except for those who are a little more tech-savvy and use password managers). As a result (and in line with best practice), you’d really need to think about layering on Multi-Factor Authentication (MFA) as well.

Single Sign-On (SSO) integration

With SSO, you can use a trusted third-party to carry out the authentication of users, and then rely on their attestation that the user is who they say they are. SSO comes in a few different flavours (which we will touch on shortly) but can mean that the management and security overheads are offloaded from your development team, allowing them to focus on what you want to do - writing a good app (not to say that doesn’t come with its own security challenges of course).

There are many SSO providers on the market. To name a few:

  • Ping
  • Okta
  • Auth0
  • Entra ID

These platforms allow integration into organisation’s existing directory solutions (such as Windows Active Directory) and/or creation of a cloud-native user directory store that supports modern authentication. They are also very likely to offer MFA out of the box, meaning another thing you don’t have to worry about, and users get the benefit of remembering a single set of credentials.

The downside - cost of course! Generally nothing in this world is free.

Both SSO and local authentication could also include options for ‘passwordless’ authentication such as magic email links, biometric authentication and push notifications.


Authorisation

Authorisation is the process of determining what actions a user or system has the right to perform based on their validated identity. It is a critical component of security, ensuring that users can only access what they are permitted to.

Once we know who a user is, we want to be able to control what they can do. Without authorisation, people would be able to view details of other people, or potentially perform administration tasks they shouldn’t be able to.

When it comes to implementing authorisation, there are numerous different ways this can be achieved, but unlike authentication it isn’t generally something you can simply offload to a third-party as such. Whilst the methods those third parties provide may well form part of your authorisation strategy (such as SAML claims, JWT tokens etc.), you’ll likely still need to map these to varying roles within your application.


It’s not all about the users!

When considering authentication and authorisation, we also need to factor in applications talking to other applications or APIs. Let’s say you want to use the latest fancy Email AI productivity tool - how can you provide it access to your mailbox, without handing over your credentials? What if you want to revoke that access? How can you limit what it can do?

Fortunately, there are answers to these challenges, and we are going to explore some of these in this article. We will be focusing on more modern protocols that are typically found in web applications and cloud environments, rather than legacy protocols such as Kerberos and LDAP.


Security Assertion Markup Language (SAML)

SAML is an open standard that facilitates the exchange of authentication data (and to an extent authorisation data) between an identity provider (IdP) and a service provider (SP), using XML-based messages and X.509 certificates.

A few of the core building blocks of SAML are:

  • Identity Provider (IdP) - An identity provider is the entity responsible for authenticating users and then issuing assertions about this process. This could be the likes of Okta, Ping, Entra ID etc. IdP user databases can vary and may be “cloud only”, synchronise to external databases (such as Windows Active Directory), or offload using another layer of SSO. It allows organisations to centralise their users and authentication, and easily layer on things such as MFA.
  • Service Provider (SP) - A service provider is the entity that provides a service to users (such as a website) and wishes to offload authentication to the IdP.
  • SAML Assertion - An assertion is the XML-based response message that the IdP passes back to the SP, showing the state of the authentication (pass/fail), the method of authentication (password, MFA, Kerberos etc.) and supplementary information that the SP may need, such as user attributes, group memberships etc.

SAML assertions are passed via the client browser, but are protected against tampering with the X.509 signatures that are used. SAML can be initiated in one of two ways:

  • IdP-Initiated - The user goes to some sort of portal (such as Okta or Microsoft’s “MyApps”), clicks a link and heads straight into the destination website already logged in.
  • SP-Initiated - The user heads to the intended website, goes to login, gets redirected to the IdP for authentication, then redirected back before being logged in.

Additionally, the signed assertion can be sent over a “front channel” (via the client browser using a HTTP POST) or a “back channel” (via direct IdP to SP communication). As far as I’m aware, front channel is the most commonly used with SAML.

Shown below is a simplified diagram illustrating the SP-initiated flow:

SAML Process

SAML is geared around authentication for end-users. That being said, the assertion can contain attributes about the user, so these can be used for authorisation decisions within your application.

On its own, SAML does not natively provide user management such as account creation. While a website may offload the authentication to the IdP, the users will still likely have to be created manually in the website first. This can be addressed where supported however, through the use of ‘System for Cross-domain Identity Management’ (SCIM). SCIM allows you to add users once (in your SSO platform), and automatically have them provisioned into the relevant applications.


Web Services Federation (WS-Fed)

I don’t really see much WS-Fed nowadays (I saw a little in Windows environments years back), but thought I’d mention it in passing. I’ve no real experience of it, but on the face of it, it is very similar to SAML in terms of its end goal. It was developed by Microsoft as part of their broader web services stack and there are differences in message exchanges and protocols (SOAP based rather than XML), but other than that - pretty similar to SAML (as far as I’m aware).

It has generally been superseded by the other protocols/frameworks we are discussing here though, so I’m not going to dwell on it any further.


OAuth2.0

Unlike SAML and WS-Fed, OAuth 2.0 is an authorisation framework, not an authentication framework. It was developed to solve a “delegated authorisation” problem that existed. It allows applications to obtain limited access to user data via a ‘consent’ process and is widely adopted.

Many applications on the web want access to our data in order to provide some additional functionality. We could just give them our password and hope they look after it (which years ago is what was happening 😱), but that’s not really a great idea for various reasons:

  • Security Risks - Sharing passwords increases the risk of unauthorised access, particularly where users have habits of re-using passwords across differing sites.
  • Lack of Granularity - Password sharing does not allow for fine-grained permissions. Anything you can do, the app/site can now do too. If all the app needed was access to your calendar, why would you want to give it full mailbox access?
  • Revocation Challenges - If a password needs to be changed, it affects all services using that password, complicating access management.
  • No Audit Trails - Legacy methods do not provide visibility into which applications accessed user data or when.
  • User Experience - If a user updated a password, and multiple sites had this cached for their purposes, they’d need to go around them all and update those as well.

With OAuth 2.0 users can consent to sharing specific bits of data with an application, without revealing their personal credentials. This is achieved through a system of tokens, which serve as temporary access keys with defined scopes and expiration times.

OAuth2.0 has a concept of ‘scopes’ meaning you can be granular in what access you permit. For example, with the Microsoft Graph APIs, you can consent to ‘Mail.Read’ and allow a service the ability to read mail, without the capability to delete mails, send mails or perform any other actions outside of this narrow scope.

With mail in mind, let’s say we want the latest AI-powered email tool to access our Office 365 mailbox, there are a few roles and terms we should be familiar with.

  • Resource Owner - Me! As the owner of the mailbox, I “own” the data (ignoring the fact it may be company “owned” for now). I can choose to authorise access (under some circumstances - more on that in a future article).
  • Resource Server - This is the “server” that hosts my mailbox. In this instance, there will clearly be more than a single server, but you get the point. Microsoft Office365 (for example) is responsible for holding the mailbox and providing various ways to access this data via protected resources APIs.
  • Client - The client is the entity that is requesting access to data on behalf of the resource owner. It refers to the software application that is requesting access to our data. The client can be a web application, mobile app, or any other type of software that needs to authenticate users and could be server-side or client-side depending on the architecture. Yeah, I know, a little confusing calling the application the client - but it is the client to the data it is trying to access.
  • Authorisation Server - The server responsible for authenticating the resource owner and issuing access tokens to the client, as well as handling authorisation requests. This could be a number of services, but in this article, we will be focussing on Entra ID (formerly known as Azure Active Directory).
  • Access Tokens and Refresh Tokens - A couple of types of tokens are issued by the authorisation server that grants the client access to the resource server (or refresh the token that does). It has a limited lifespan and is used to authenticate requests for data.
  • Scopes - Scopes are pre-defined sets of permissions that allow you to be granular in what you grant access to. In the instance of our AI email tool, it may require the Microsoft Graph permissions of ‘Mail.Read’ or perhaps ‘Mail.ReadWrite’.

There are a number of different OAuth2.0 flows, that vary based on the use-case being addressed. Some communications take place on a front channel, and some the back channel. We aren’t going to explore them all here for the sake of simplicity.

A simplified diagram illustrating the more common “authorisation code flow” is shown below.

OAuth2.0 Flow

The main drawback to OAuth2.0, was that it was not designed for authentication. Due to its popularity however, this is exactly what it started getting used as. This presented a number of pitfalls and security concerns, such as lack of user information, no logout mechanism, token interception and potential replay attacks.

If you want to get deep into OAuth2.0 (and some of the challenges I mentioned), then by far the best video I’ve seen on the subject is the following from Nate Barbettini (who was a developer advocate at Okta at the time) - it’s well worth a watch.


Open-ID Connect (OIDC)

To address the concerns noted above, OIDC was developed as an additional authentication layer built on top of the OAuth2.0 framework. It allows applications (or rather ‘clients’) to verify the identity of users based on the authentication performed by an authorisation server and uses uses standardised JSON Web Tokens (JWT) to convey user identity information.

Most of the terminology in relation to OIDC is the same as with OAuth2.0, as they are essentially the same! Some other terms you may come across are shown below.

  • ID Token - A foundational building block in OIDC is the ID Token. This is provided as a JSON Web Token (JWT) and contains information about the authenticated user and any ‘claims’ such as their identity, email address, etc. This token gets cryptographically signed by the authorisation server, enabling the application (client) to trust the identity of the user.
  • Relying party - The relying party is the application or service that trusts the identity information provided by OIDC. Essentially this is the backend servers that run the application, that receive a signed ID token and uses it to authenticate the user, allowing them to access the application without needing to create a new account or manage separate credentials.
  • OIDC Providers - These are services that manage user identities and undertake authentication. Ever seen those “Sign in with Google” or “Sign in with Facebook” buttons all over the show? That’s (hopefully!) using OIDC - Google and Facebook are the OIDC providers in these instances. They utilise existing databases and identity information, so that other applications can facilitate SSO.
  • User Info API Endpoint - The User Info API Endpoint component of OIDC allows applications to retrieve additional information about the authenticated user. This endpoint provides identity details such as the user’s name, email, and profile picture, which are returned as claims in the JWT.
  • Claims - As mentioned above, the Identity Token in JWT format contains claims relating to the user. There are common standardised claims used as part of the OIDC proess. The main ones are:
    • sub - A subject identifier that acts as a unique ID value for the user.
    • name - The full name of the user.
    • email - The email address of the user.
    • picture - A URL to a user’s profile picture where used.
  • Scopes - Like OAuth2.0, OIDC uses specific scopes, purely for the purposes of consenting to exchanging identity information. They are:
    • openid - This has to be included and indicates that the application (client) is requesting an ID token.
    • profile - Requests for consent to access the user’s default profile claims we mentioned above (e.g., name, picture).
    • email - Requests access to the user’s email address.

As with OAuth2.0, there are a number of different types of flow that exist for various different use cases. If I were to draw a diagram of the OIDC flow, it would look much the same as the OAuth2.0 flow. The main differences would be as follows:

  • Scopes - The scopes would include the special value ‘openid’ that determines this is an OIDC flow, and not just a regular OAuth2.0 flow. Additional scopes such as ‘profile’ are likely also included.
  • Consent - If the user hasn’t already consented, then they will be asked for consent the first time they login. Obviously the scopes this time however just relate to identity and profile information for the purposes of signing in.
  • Token Exchange - The token exchange this time is a little different. With authorisation code flow, this is again on the back channel, but instead of access tokens and refresh tokens, it instead retrieves an access token and ID token.
  • User Info - The final major difference, is that the client can use the access token to retrieve further information about the user from a specific user info API endpoint.

Similarly to SAML, OIDC does not provide account management functionality, but again SCIM is often used for these provisioning/deprovisioning purposes to streamline operations.


SAML vs OIDC

Given the glaring similarities between SAML and OIDC, you’re probably wondering which you should use?

OIDC is a more modern-protocol, uses RESTful API endpoints, lightweight JWT tokens (no one really likes XML :shudder:), but beyond that, you could argue either would work just fine. A lot of which you go for probably depends on your target audience and your application. Some thoughts below:

  • Is your application going to be for personal consumers? If so, OIDC and easy integration with OIDC providers such as Google and Facebook will probably be quite appealing.
  • Are you writing modern apps such as Smartphone apps or Single-Page Apps (SPAs)? If so, SAML wasn’t really designed for them, so you’re probably better off going for OIDC.
  • Is your application geared more towards Enterprise organisations? Chances are you’ll find them more receptive and familiar with SAML. It has stood the test of time and is widely supported by any of the major SSO platforms we touched on earlier (though they do of course support OIDC as well.)
  • Is consent a key concern? If so OIDC explicitly requires consent even for exchanging identity info used for login, whereas you can’t easily get the same with SAML.

Personally, if I were starting out writing a new application today (not that I could 😉), I’d opt for OIDC from the outset. This is generally what I see elsewhere. However, I’m not an expert in these protocols, and have not done this comaprison justice.

I’m hoping in future articles (for my own benefit more than anything else!) to go really deep on them, so perhaps we can work it out then!


Conclusion

Hopefully this has given you a bit of a grounding in some of the authentication/authorisation technologies used, before we get into looking at the specifics as they relate to Entra ID. In the next article, we are going to start exploring how we configure Entra ID to work with some of the elements we’ve looked at, and the quirks that come with it.

As always, if you have any questions or comments, please get in touch.