Authentication vs. Authorization
Concept
Authentication (AuthN) and authorization (AuthZ) answer two different questions, and the entire access-control model of a system depends on keeping that distinction sharp. Authentication answers "are you who you claim to be?" — verifying an identity, typically via credentials (a password, a passkey, a certificate, a federated identity token). Authorization answers "are you allowed to do what you're trying to do?" — deciding, for an already-verified identity, what resources and actions it can access. Authentication always runs first: authorization cannot proceed until identity is established, because there is nothing to check permissions against otherwise.
In practice the two are implemented by different, purpose-built protocols, and mixing them up is the single most common security mistake in this space. SAML and OpenID Connect (OIDC) are authentication protocols — they exist to establish who a user is and hand back an identity assertion (SAML) or an ID token (OIDC), and are what powers single sign-on. OAuth 2.0 is an authorization framework — it exists to grant a piece of software delegated access to a specific resource on a user's behalf (e.g., "let this app read my calendar"), and its output is an access token scoped to that resource, not an identity claim. OIDC is built as a thin identity layer on top of OAuth 2.0 specifically because OAuth alone doesn't authenticate anyone — a fact that gets lost constantly in practice.
Tradeoffs
| Protocol | What it actually proves | Correct use | Common misuse |
|---|---|---|---|
| SAML | Identity, via signed XML assertion from an identity provider | Enterprise SSO into web apps, especially legacy/enterprise IdPs | XML signature validation is complex to implement correctly; a gap there opens signature-wrapping attacks |
| OAuth 2.0 | Delegated authorization — that a token holder may access a specific scoped resource | An app requesting scoped access to a user's data on another service (e.g. "read my files") | Using an OAuth access token to authenticate a user — access tokens prove authorization, not identity, and using them as an identity check is a well-known class of vulnerability |
| OIDC | Identity, via a signed JWT ID token, layered on OAuth 2.0's flow | Modern SSO / "log in with X" flows that also need standard, JSON-based tooling (vs. SAML's XML) | Confusing the ID token (identity) with the access token (authorization) it's issued alongside — they answer different questions and aren't interchangeable |
The underlying tradeoff isn't really protocol-vs-protocol — it's how much complexity a team is willing to own to get each guarantee right. SAML's XML-based signature model is powerful but easy to implement subtly wrong; OAuth's flexibility as a general-purpose delegation framework is exactly what makes it easy to misuse as an authentication mechanism it was never designed to be. Most real-world authentication vulnerabilities in this space trace back to that kind of misconfiguration or protocol misuse, not to a flaw in the protocols themselves.
When to use / when not to
- Use OIDC (or SAML, for legacy/enterprise IdP integration) whenever the goal is establishing who a user is — login flows, SSO, session creation.
- Use OAuth 2.0 whenever the goal is granting a piece of software scoped, delegated access to a resource — third-party integrations, "connect your account" flows, API access on a user's behalf.
- Never use a bare OAuth access token as proof of identity — if authentication is the actual requirement, use OIDC (which issues both an ID token for identity and, separately, an access token for any authorization needed) rather than trying to make OAuth alone do double duty.
- Don't build custom authentication or session logic when a standard protocol covers the case — implementing SAML or OIDC correctly is hard enough with mature libraries; a hand-rolled equivalent multiplies the attack surface for no real benefit.
Common pitfall
Treating "the user has a valid token" as sufficient without checking which token and for what. An access token proves the bearer was granted a specific, scoped authorization — it does not prove who the underlying user is, and an ID token proves identity but says nothing about what that identity is allowed to do beyond having been authenticated. A system that checks only "is there a token" and skips the AuthN/AuthZ distinction ends up either granting access to callers who were never actually authenticated, or authenticating a user and then failing to enforce any authorization boundary at all — both are real vulnerability classes, not theoretical ones.
Engineering Lens
The design-review test isn't whether a system "has auth" — it's being able to state, for any given endpoint, exactly which layer is doing the checking and on what basis: what proves the caller's identity, separately from what proves the caller is allowed to perform this specific action on this specific resource. Systems that collapse the two into one check ("if there's a valid session, allow it") tend to work fine until a legitimate, authenticated user hits an endpoint they were never supposed to reach — the classic broken-access-control failure mode, which is an authorization gap wearing an authentication system's clothes. Naming the two checks separately, even when one library happens to handle both, is what keeps that gap visible during review instead of discovered in an incident.
Sources
- Authn vs. authz: How are they different? — Cloudflare
- Authentication protocols compared: SAML, OAuth 2.0, OIDC — Cisco Duo
- Security Vulnerabilities in SAML, OAuth 2.0, OpenID Connect, and JWT — Security Boulevard