OAuth 2.0
OAuth 2.0 is an authorization framework that allows a client application to obtain limited access to a resource on behalf of a user, without the client ever handling the user’s credentials.
Defined in RFC 6749, OAuth 2.0 is about delegated authorization, not authentication (authentication is layered on via OpenID Connect).
Core Problem OAuth Solves
Without OAuth:
- App asks for username/password.
- App stores credentials.
- Huge security risk.
- No granular access control.
- No revocation per app.
With OAuth:
- User authenticates with trusted Identity Provider (IdP).
- IdP issues a token to the client.
- Client uses token to access APIs.
- Credentials are never shared.
This enables:
- Third-party integrations
- Mobile + SPA architectures
- API ecosystems
- Enterprise SSO environments
Core Roles in OAuth
OAuth defines four roles:
| Role | Description |
|---|---|
| Resource Owner | The user |
| Client | The application requesting access |
| Authorization Server | Issues tokens (IdP) |
| Resource Server | API that validates tokens |
In Azure AD terms:
- Resource Owner → User
- Client → Web app / SPA / mobile app
- Authorization Server → Azure AD
- Resource Server → Your API
Tokens in OAuth
OAuth itself does not mandate token format.
Common tokens:
- Access Token → Used to call APIs
- Refresh Token → Used to obtain new access tokens
Access tokens may be:
- JWT (self-contained)
- Opaque (reference token requiring introspection)
OAuth doesn’t require JWT — that’s an implementation choice.
Authorization Grant Types (Flows)
OAuth 2.0 defines several flows for different scenarios.
Authorization Code Flow (Most Important)
Used by:
- Server-side web apps
- SPAs (with PKCE)
- Mobile apps
High-level flow
- Client redirects user to Authorization Server.
- User authenticates.
- Server returns an authorization code.
- Client exchanges code for access token.
- Client calls API with access token.
This keeps tokens off the browser (for confidential clients).
Authorization Code + PKCE (Modern Standard)
PKCE = Proof Key for Code Exchange.
Required for:
- SPAs
- Mobile apps
- Public clients
Prevents interception attacks by binding the authorization code to a cryptographic proof.
Today, Authorization Code + PKCE is the recommended default flow.
Client Credentials Flow
Used for:
- Service-to-service communication
- Backend jobs
- Daemons
No user involved.
Client authenticates using:
- Client ID + secret
- Or certificate
Token represents the application itself.
Device Code Flow
Used for:
- TVs
- IoT
- CLI tools
User authorizes on a separate device.
Deprecated Flows
- Resource Owner Password Credentials (ROPC)
- Implicit Flow
These are now discouraged for security reasons.
Scopes and Consent
OAuth introduces scopes — granular permissions.
Example:
read:orders
write:orders
read:profile
User consents to specific scopes.
Access token contains granted scopes.
API enforces based on scope claims.
This enables:
- Principle of least privilege
- Third-party integrations with limited access
What OAuth Is NOT
OAuth is NOT:
- An authentication protocol (that’s OpenID Connect)
- A user session mechanism
- A replacement for authorization logic inside your API
OAuth answers:
“Can this client access this resource?”
It does NOT answer:
“Who is the user?” (OIDC does)
OAuth vs OpenID Connect (Critical Distinction)
OAuth = Authorization OIDC = Authentication layer on top of OAuth
When you log in with Microsoft / Google:
- OAuth flow runs
- OIDC adds an ID Token (JWT)
- ID Token contains identity claims
In enterprise systems, you almost always use OAuth + OIDC together.
High-Level Architecture View
In a microservices / API environment:
User
↓
Client App
↓
Authorization Server (Azure AD, Auth0, etc.)
↓
Access Token
↓
API Gateway
↓
Microservices
Best practice:
- Validate tokens at API gateway boundary
- Propagate identity via claims
- Avoid passing raw tokens between internal services
- Use Client Credentials for service-to-service auth
Security Model Summary
OAuth relies on:
- TLS (HTTPS mandatory)
- Short-lived access tokens
- Refresh tokens stored securely
- Token validation (issuer, audience, expiry)
- Scope enforcement
- PKCE for public clients
Common enterprise misconfigurations:
- Long-lived tokens
- Overly broad scopes
- Skipping audience validation
- Using ROPC flow
- Storing tokens in localStorage (SPA)
Practical .NET Context
Typical ASP.NET Core setup:
builder.Services
.AddAuthentication("Bearer")
.AddJwtBearer("Bearer", options =>
{
options.Authority = "https://login.microsoftonline.com/{tenant}";
options.Audience = "api://orders-api";
});
This integrates OAuth-issued tokens into the middleware pipeline.
For service-to-service:
ConfidentialClientApplicationBuilder
.Create(clientId)
.WithClientSecret(secret)
.Build()
.AcquireTokenForClient(scopes)
Conceptual Summary
OAuth 2.0 is fundamentally about:
- Delegating access
- Avoiding credential sharing
- Issuing time-bound, scoped tokens
- Separating authentication from resource access
It is the foundation of:
- API security
- Modern SSO
- Cloud identity
- Zero-trust architectures