Authentication and authorization get used almost interchangeably in casual conversation, and confused constantly in interviews, despite being genuinely different questions with different mechanisms answering each one. This post draws that line clearly first, then covers every major method under each - Basic Auth, Sessions, OAuth, OAuth 2.0, OpenID Connect, JWT, SSO, and how authorization decisions actually get made via RBAC and ABAC - with analogies, real examples, and how each one shows up in Azure specifically.
The One-Sentence Distinction
Authentication proves who you are. Authorization proves what you're allowed to do. These are checked separately, even when they happen back to back. A user can be fully, successfully authenticated and still get a 403 Forbidden trying to access something they're not authorized for.
Think of a concert venue. Showing your ticket at the door proves you're a legitimate attendee - that's authentication. Once inside, your wristband color determines whether you can access the VIP lounge or only the general floor - that's authorization. Having a valid ticket says nothing about which areas you're allowed into - those are two separate checks, at two separate points, even though they happen close together.
Basic Auth: The Oldest, Simplest Method
Basic Auth combines a username and password, base64-encodes them together, and sends the result in the Authorization header on every single request.
-- The credentials "alex:mypassword" become:
Authorization: Basic YWxleDpteXBhc3N3b3Jk
-- Base64 is ENCODING, not ENCRYPTION - it is
-- trivially reversible by anyone who intercepts it.
-- This ONLY becomes safe over HTTPS, where the
-- transport layer itself is encrypted.
Think of writing your password on a postcard instead of sealing it in an envelope. Base64 makes it slightly less immediately readable at a glance, but anyone who actually picks it up can read it in seconds. HTTPS is the sealed, tamper-evident courier bag around that postcard - without it, Basic Auth is genuinely dangerous.
Basic Auth still shows up in internal tooling, simple server-to-server calls behind a firewall, or as a stopgap for low-risk endpoints. It's rarely appropriate for anything user-facing or handling sensitive data, since credentials are resent on every single request rather than exchanged once for a limited-scope token.
A Quick, Clarification: API Keys vs Basic Auth vs Subscription Keys
These three terms get used almost interchangeably in casual conversation, but they're not quite the same thing, and mixing them up causes real confusion in practice.
Basic Auth is a username and password, base64-encoded, sent every request, as covered above. An API key is a single opaque string with no username involved, usually sent as a header or query parameter, identifying which application or account is calling, not a specific human user. A subscription key, specifically in Azure API Management, is a particular flavor of API key scoped to a Product, covered in an earlier post on this blog about APIM - it answers which subscription plan a caller is on, not who the caller is.
None of these three actually prove identity in any strong sense - they prove possession of a credential, whether a password, a key, or a subscription key. This is exactly why real production systems frequently combine one of these with OAuth2/OIDC - the API key or subscription key controls access tier and rate limits, while the OAuth token establishes actual, verifiable identity. This same layered pattern was covered concretely in an earlier post on this blog about Azure APIM, where a subscription key and an OAuth token are validated together, answering two different questions in the same request.
Session-Based Authentication: The Server Remembers You
In session-based authentication, a user logs in once with credentials, the server creates a session and stores its state server-side, then gives the browser a session ID, usually via a cookie, to present on every subsequent request instead of re-sending credentials each time.
A login request verifies credentials and creates a session, stored in memory, a database, or a cache like Redis, and returns a Set-Cookie header containing something like sessionId=abc123. Every future request automatically includes that cookie. The server looks up "abc123" in its session store, finds the associated user, and knows who's making the request without re-checking a password every time.
Think of a coat check at a restaurant. Handing over your coat once, logging in, gets you a numbered ticket. Presenting that ticket, the session ID, for the rest of the evening retrieves your coat without needing to re-prove ownership each time - the coat check itself, the server, is what's actually holding onto the state.
The real limitation is that because the server holds the actual session state, scaling horizontally across multiple servers requires that every server can access the same shared session store. A server that doesn't have "abc123" in its own memory can't recognize that session unless the store is centralized, like Redis, or the session is somehow shared across instances. This is a genuine architectural constraint sessions introduce that token-based approaches largely avoid.
OAuth vs OAuth 2.0: Not the Same Protocol
The distinction people miss most often: "OAuth" without a version number technically refers to OAuth 1.0, an older protocol that required cryptographically signing every single request - genuinely painful to implement correctly. OAuth 2.0 is a substantially different, simpler protocol built around bearer tokens sent over HTTPS instead of signed requests. When anyone says "OAuth" today without qualification, they almost always mean OAuth 2.0 - OAuth 1.0 is effectively extinct in modern development.
OAuth 1.0 required every request to be cryptographically signed using a shared secret, complex to implement correctly, with no built-in token expiration concept. OAuth 2.0, what "OAuth" means today, uses bearer tokens - "whoever holds this token is authorized" - sent over HTTPS, with a built-in concept of token expiration and refresh, and multiple grant types for different scenarios, including client credentials and authorization code flows.
OAuth 2.0 is fundamentally a framework for delegated authorization - letting one application access resources on behalf of a user, or another system, without ever handling that user's actual password. An earlier post on this blog covered the mechanics of this in detail: Client Credentials Flow for service-to-service scenarios, Authorization Code Flow for real user logins, access tokens, and refresh tokens.
OpenID Connect (OIDC): The Piece That Makes OAuth2 Usable for Login
OAuth 2.0, by itself, is an authorization framework - it's designed to grant an application access to a resource, not to prove who a user is. A raw OAuth2 access token technically doesn't guarantee anything about identity; it only proves the holder was granted some scope of access. This is a genuinely common point of confusion - "Sign in with Google" and "Sign in with Microsoft" buttons are commonly described as using OAuth, but strictly speaking, they're using OpenID Connect, a layer built directly on top of OAuth 2.0 specifically to add authentication.
OAuth 2.0 alone answers whether an application is allowed to access a resource on the user's behalf. It does not reliably answer who the user is, specifically. OpenID Connect adds a standardized identity layer on top of OAuth 2.0's existing authorization flow, introducing the ID token - a JWT specifically containing identity claims like name, email, and a unique user ID - distinct from the access token.
Where OAuth2 alone issues an access token for calling APIs, OIDC additionally issues an ID token, a JWT whose entire purpose is describing who the user is, not what they can access. Both tokens are often returned together in the same OIDC flow, but they answer different questions and are used differently: the access token gets sent to APIs to prove authorization, while the ID token gets read by the application itself to know who just logged in.
{
"access_token": "eyJhbGciOiJ...",
"id_token": "eyJhbGciOiJ...",
"token_type": "Bearer",
"expires_in": 3600
}
The decoded ID token payload carries identity claims rather than authorization scopes:
{
"sub": "a1b2c3d4",
"name": "Manohari Jayachandran",
"email": "user@example.com",
"iss": "https://login.microsoftonline.com/...",
"aud": "your-app-client-id",
"exp": 1719399600
}
The one-sentence summary worth remembering: OAuth 2.0 answers whether an app is allowed to do something - it's authorization. OpenID Connect adds who the user doing it actually is - it's authentication, layered on top of OAuth2's existing machinery rather than replacing it. This is exactly why "Sign in with Google" or "Sign in with Microsoft" buttons work the way they do - they're OIDC flows, using OAuth2 underneath to handle the actual token exchange.
JWT: A Token Format, Not an Authentication Method
The distinction that trips people up in interviews most often: JWT, JSON Web Token, is not itself a way of authenticating anyone. It's a specific, structured format that a token can take. OAuth 2.0 is commonly used to issue a JWT as the resulting access token, but OAuth2 and JWT are answering different questions - OAuth2 is the protocol for how a token gets issued and exchanged; JWT is simply the shape that token happens to be in.
A JWT has three parts, separated by dots - header, payload, and signature. This is the same structure covered in more depth in an earlier post on this blog about OAuth token flows: the header names the signing algorithm, the payload carries claims about who issued it, who it's for, when it expires, and what scopes or roles it grants, and the signature cryptographically proves the token hasn't been tampered with.
Critically, a JWT is signed, not encrypted. Anyone holding the token can read every claim inside it, even without the ability to forge a new one. This is why sensitive data should never be placed directly in a JWT's payload.
Stated plainly: Basic Auth and Sessions are both complete authentication mechanisms on their own. OAuth2 is a framework for authorization and delegated access. JWT is neither of those - it's a data format that OAuth2, and other systems, commonly use to package the result of a successful authentication or authorization decision into something portable and independently verifiable.
SSO: Single Sign-On, Built on Top of What's Already Covered
Single Sign-On lets a user authenticate once, with one identity provider, and gain access to multiple separate applications without logging in again for each one. SSO is not a new authentication mechanism of its own - it's an architecture built on top of session-based auth and OpenID Connect, covered just above, applied across multiple applications instead of just one.
Think of a single hotel key card that opens the room, the gym, the pool area, and the parking garage - one check-in at the front desk, the identity provider, and every other door on the property recognizes that same card without asking for ID again. Without SSO, it would be like getting a separate, differently-shaped key for every single door, each requiring its own check-in process.
Without SSO, a user manages separate logins and separate passwords for every application, logging in repeatedly across each one. With SSO, the user logs into the Identity Provider once, and every application trusting that same Identity Provider recognizes the user's session or token without asking them to log in again.
Mechanically, the first application a user visits redirects them to a central Identity Provider if they aren't already authenticated. The user logs in once at the Identity Provider, which issues a token, commonly a JWT via OAuth2 or OpenID Connect, or sets a session with itself. When the user then visits a second application, that application also redirects to the same Identity Provider - but since the user already has a valid session or token from the first login, they're recognized immediately and redirected back, fully authenticated, without ever seeing a login form the second time.
Two protocols are commonly used to implement SSO. SAML, Security Assertion Markup Language, is older and XML-based, still common in large enterprise environments. OpenID Connect, built directly on top of OAuth 2.0, adds a standardized identity layer onto OAuth's authorization framework - this is the modern, most common way SSO is implemented today, and it's why OpenID Connect is often described as "OAuth2 plus authentication."
Azure AD, now Microsoft Entra ID, plays exactly this role across Microsoft 365, the Azure Portal, and any custom application registered against the same tenant - logging into one Microsoft-connected application means every other application trusting that same Azure AD tenant recognizes the session without a repeated login. This is the same Azure AD covered in an earlier post on this blog about OAuth token flows, now applied across multiple applications instead of just one.
How This Connects to Azure Specifically
The full picture ties together two earlier posts on this blog. Azure AD, now called Microsoft Entra ID, issues a token after verifying identity - this is authentication, using OAuth 2.0 as the protocol, covered in depth in an earlier post on Azure AD and OAuth token flows. That token is a JWT - the format, not the method. Azure API Management's validate-jwt policy checks the token's signature, expiry, issuer, and audience at the gateway, before the backend ever runs, covered in depth in an earlier post on Azure APIM. Claims inside that JWT, like app roles or scopes, determine what the caller is actually allowed to do once authenticated - checking those specific claims is authorization, layered on top of the authentication that already happened.
Where authentication ends and authorization begins in this Azure flow is worth being precise about. Azure AD verifying the caller's identity and issuing a valid, signed JWT is authentication - it answers who this is. APIM's validate-jwt policy checking that the token is genuinely valid, not expired, correctly signed, right audience, is still part of confirming the authentication is real. The moment a policy checks a specific claim, such as whether this token has the Orders.Read role, that's authorization - a separate question answered using data carried inside the already-authenticated token.
RBAC vs ABAC: How Authorization Decisions Actually Get Made
Everything above establishes who a caller is. This section covers how a system actually decides what that caller can do - the real mechanism behind checking whether a token has a specific role, mentioned just above.
Role-Based Access Control, RBAC, attaches permissions to roles, and users are assigned to one or more of those roles. An Admin role can read, write, and delete. An Editor role can read and write. A Viewer role can only read. A user's permissions are whatever their assigned role or roles grant - simple, predictable, and easy to reason about.
Think of a hospital ID badge. A badge marked Nurse opens certain doors and certain systems. A badge marked Doctor opens more. The badge doesn't know anything about the specific person wearing it beyond their assigned role - two different nurses with the same role badge get identical access, no matter how their individual situations might differ.
Attribute-Based Access Control, ABAC, decides permissions dynamically, based on a combination of attributes evaluated at the moment of the request, rather than a fixed role assignment. A rule might allow access to a patient record only if the requesting user's department matches the patient's assigned department, the request happens during business hours, and the record isn't flagged as restricted. The same user might be allowed access to one record and denied access to another, based on attributes of the specific resource and context, not a single fixed role.
Think of airport security screening. Whether a specific bag gets flagged for additional screening depends on a combination of factors evaluated in that specific moment - what's in the bag, which flight, current threat level, random selection - not a single fixed role the passenger was permanently assigned at check-in. The decision is made fresh, per situation, based on multiple attributes together.
RBAC fits when a permission structure is genuinely role-shaped - a manageable number of roles, each with a clear, fairly static set of permissions. ABAC fits when access decisions genuinely depend on context that changes per request - resource ownership, time, location, sensitivity level, or the relationship between the user and the specific resource. Many real systems use both together, a coarse RBAC layer for broad access tiers like Admin versus Standard User, with finer ABAC-style rules layered on top for specific sensitive resources.
This connects directly back to the Azure JWT example above: a role claim inside a JWT, like Orders.Read, being checked by APIM is RBAC in action - the caller was assigned that role, and the token carries proof of it. A more advanced setup might layer ABAC on top - even with a valid Orders.Read role, a specific policy might further restrict access based on which region the order belongs to, matching an attribute on the caller's own token against an attribute on the specific resource being requested.
Choosing the Right Approach
Basic Auth fits internal tooling, simple server-to-server calls behind a firewall, and low-risk scenarios only. Session-based auth fits traditional server-rendered web apps, where the server already controls the full request lifecycle and horizontal scaling isn't a primary concern. OAuth 2.0 combined with JWT fits APIs, single-page applications, mobile apps, service-to-service integration, and anything needing delegated access without sharing real passwords, or anything that needs to scale horizontally without shared server-side session state.
Key Lessons
Authentication proves identity; authorization proves permission - they're checked separately, and passing one doesn't guarantee passing the other.
API keys, subscription keys, and Basic Auth all prove possession of a credential, not identity - none of the three is a strong identity check on its own.
Basic Auth is simple but only safe over HTTPS, since base64 encoding is trivially reversible, not real encryption.
Session-based auth keeps state on the server, which is simple for single-server apps but requires a shared session store to scale horizontally.
OAuth and OAuth 2.0 are genuinely different protocols - OAuth 2.0 is what "OAuth" means today, using bearer tokens instead of OAuth 1.0's cryptographic request signing.
OAuth 2.0 alone only handles authorization - OpenID Connect is the layer built on top of it that adds real authentication, via a separate ID token distinct from the access token.
JWT is a token format, not an authentication method - OAuth2 is a common way to issue one, but the two answer different questions.
SSO is not a separate mechanism - it's session and OAuth concepts applied across multiple applications trusting one shared identity provider, commonly implemented today via OpenID Connect on top of OAuth 2.0.
In a real Azure setup, Azure AD handles authentication and issues a JWT, while claims inside that JWT, checked by APIM or the backend, handle authorization - two distinct steps using the same token.
RBAC assigns fixed permissions to roles, simple and predictable; ABAC decides access dynamically based on multiple attributes at request time - real systems often layer both together.
Summary
Authentication and authorization are two separate questions - who are you, and what are you allowed to do - answered by different mechanisms that often work together but are never the same check. Basic Auth and session-based authentication are complete, older methods of proving identity. OAuth 2.0 is a modern framework for delegated authorization, built around bearer tokens rather than OAuth 1.0's cryptographic signing. JWT is not a method at all - it's the structured format a token commonly takes, readable by anyone holding it but not forgeable without the signing key. Seeing how Azure AD, JWTs, and APIM's validation policy fit together, authentication first, authorization layered on top using claims inside the same token, is what turns these five terms from a list of buzzwords into a coherent system.
Originally published at TechStack Blog: https://www.techstackblog.com/post.html?slug=authentication-vs-authorization-explained
Related reading on TechStack Blog:
Azure AD and OAuth Token Flows: https://www.techstackblog.com/post.html?slug=azure-ad-oauth-token-flows-explained
Azure API Management Part 1: https://www.techstackblog.com/post.html?slug=azure-apim-explained-part1
More from TechStack Blog: CS Fundamentals: https://www.techstackblog.com/category.html?cat=cs-fundamentals
Azure: https://www.techstackblog.com/category.html?cat=azure









Top comments (0)