Skip to content

Authentication

Chapter 18: Authentication & Authorization

Section titled “Chapter 18: Authentication & Authorization”

Comprehensive Guide to Securing Your System

Section titled “Comprehensive Guide to Securing Your System”

Understanding the difference between authentication and authorization is fundamental to building secure systems.

Authentication vs Authorization
============================
┌─────────────────────────────────────────────────────────────┐
│ YOUR IDENTITY │
│ │
│ Authentication (WHO are you?) │
│ ───────────────────────────────── │
│ "Prove you are who you claim to be" │
│ │
│ Methods: │
│ • Password │
│ • Biometric │
│ • Security token │
│ • Certificate │
│ │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ YOUR PERMISSIONS │
│ │
│ Authorization (WHAT can you do?) │
│ ───────────────────────────────── │
│ "Based on who you are, here's what you can access" │
│ │
│ Examples: │
│ • User can read file A │
│ • Admin can delete users │
│ • Premium user can access premium features │
│ │
└─────────────────────────────────────────────────────────────┘
Typical User Session Flow
========================
┌─────────┐ ┌─────────────┐ ┌──────────┐ ┌─────────┐
│ User │────▶│ Login │────▶│ Validate │────▶│ Session │
│ Enters │ │ Form │ │ Creds │ │ Created │
│Password │ └─────────────┘ └──────────┘ └─────────┘
└─────────┘ │
┌─────────┐ ┌─────────────┐ ┌──────────┐ │
│ Response│◀────│ Return │◀────│ Check │◀────────┘
│to User │ │ JWT/ │ │ Session │
│ │ │ Cookie │ │ in DB │
└─────────┘ └─────────────┘ └──────────┘

Session-based authentication is the traditional approach where the server maintains session state.

Session-Based Authentication
==========================
Step 1: User Logs In
┌────────┐ ┌──────────┐ ┌─────────┐
│ Client │────────▶│ Server │────────▶│ Database│
│ │ │ │ │ │
│ POST │ │ Validate │ │ Check │
│ /login │ │ creds │ │ user │
│user=abc│ │password │ │ │
│pass=xyz│ │ │ │ │
└────────┘ └──────────┘ └─────────┘
Step 2: Server Creates Session
┌────────┐ ┌──────────┐ ┌─────────┐
│ Client │◀────────│ Server │────────▶│ Database│
│ │ │ │ │ │
│ │ │ Create │ │ Insert │
│ Set │ │ session │ │ session │
│Cookie: │ │ in DB │ │ record │
│SESSID=│ │ │ │ │
│abc123 │ │ │ │ │
└────────┘ └──────────┘ └─────────┘
Step 3: Subsequent Requests
┌────────┐ ┌──────────┐ ┌─────────┐
│ Client │────────▶│ Server │────────▶│ Database│
│ │ │ │ │ │
│ GET │ │ Lookup │ │ Validate│
│ /data │ │ session │ │ session │
│Cookie: │ │ by ID │ │ │
│SESSID= │ │ │ │ │
│abc123 │ │ │ │ │
└────────┘ └──────────┘ └─────────┘
StorageProsConsUse Case
In-MemoryFastLost on restartDevelopment
RedisFast, persistentExtra infrastructureProduction
DatabasePersistentSlowerSimple apps
Cookie (Signed)No server storageSize limits, securityMicroservices
Session Security Checklist
==========================
✓ Use secure, HTTPOnly cookies
✓ Set appropriate cookie expiration
✓ Regenerate session ID after login
✓ Implement session timeout
✓ Store session data encrypted
✓ Use secure random session IDs

JWT (JSON Web Tokens) provide stateless authentication.

JWT Token Structure
==================
┌─────────────────────────────────────────────────────────────┐
│ JWT Format │
│ │
│ eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 │
│ .eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiw │
│ iYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0 │
│ .SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c │
│ │
│ ┌──────────┬──────────────┬────────────────────┐ │
│ │ Header │ Payload │ Signature │ │
│ │ (Base64) │ (Base64) │ (Base64) │ │
│ └──────────┴──────────────┴────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
{
"alg": "RS256",
"typ": "JWT",
"kid": "key-id-123"
}
{
"iss": "https://auth.example.com",
"sub": "user-123",
"aud": "my-api",
"exp": 1700000000,
"iat": 1699999999,
"nbf": 1699999999,
"jti": "unique-token-id",
"name": "John Doe",
"email": "john@example.com",
"role": "admin",
"permissions": ["read", "write", "delete"]
}
# RS256 (RSA Signature with SHA-256)
import jwt
import rsa
# Generate key pair
(private_key, public_key) = rsa.newkeys(2048)
# Create token
payload = {
"sub": "user-123",
"role": "admin"
}
token = jwt.encode(payload, private_key, algorithm="RS256")
# Verify token
decoded = jwt.decode(token, public_key, algorithms=["RS256"])
AspectJWTSession
StorageClient-sideServer-side
ScalabilityStateless (easy)Requires shared storage
Cookie SizeLarger (token in cookie)Smaller (session ID)
RevocationComplex (needs blocklist)Simple (delete session)
MobileEasier (header)Requires custom impl.
SecurityVulnerable to XSSVulnerable to CSRF

OAuth 2.0 is the industry standard for authorization and delegated access.

OAuth 2.0 Flow (Authorization Code Grant)
=========================================
┌─────────┐ ┌──────────┐
│ User │ │ Auth │
│ Browser │ │ Server │
└────┬────┘ └────┬─────┘
│ │
│ 1. Click "Login with Google" │
│────────────────────────────────────▶│
│ │
│ 2. Redirect to Google │
│◀────────────────────────────────────│
│ (Authorization Request) │
│ │
│ 3. User enters credentials │
│────────────────────────────────────▶│
│ │
│ 4. Google shows consent screen │
│◀────────────────────────────────────│
│ │
│ 5. User approves │
│────────────────────────────────────▶│
│ │
│ 6. Redirect with auth code │
│◀────────────────────────────────────│
│ (code=abc123) │
│ 7. Exchange code for tokens
│────────────────────────────────────▶┐
│ │ Your Server
│ 8. Return tokens │
│◀────────────────────────────────────┘
│ (access_token, refresh_token)
│ 9. Use access token
│────────────────────────────────────▶┐
│ │ Google API
│ 10. Return user info │
│◀────────────────────────────────────┘
Grant TypeUse CaseFlow
Authorization CodeWeb apps, MobileRedirect-based
Authorization Code + PKCEMobile, SPAsMore secure
Client CredentialsM2M, Server-to-serverNo user involved
Device CodeSmart TVs, IoTLimited input devices
Refresh TokenLong-lived sessionsGet new access tokens
Access Token
============
- Short-lived (typically 1 hour)
- Used to access resources
- Include in Authorization header
- Cannot be revoked (until expiry)
Authorization: Bearer eyJhbGci...
─────────────────────────────────────────
Refresh Token
============
- Long-lived (days/weeks)
- Used to get new access tokens
- Stored securely server-side
- Can be revoked
POST /oauth/token
{
"grant_type": "refresh_token",
"refresh_token": "abc123..."
}

API keys are simple tokens for server-to-server communication.

API Key Authentication
====================
Header-based:
X-API-Key: sk_live_abc123def456
Query string:
GET /api/data?api_key=sk_live_abc123def456
Basic Auth:
Authorization: Basic base64(api_key:)
─────────────────────────────────────────
Types:
┌────────────────┬──────────────────────────────────┐
│ Type │ Description │
├────────────────┼──────────────────────────────────┤
│ Public │ Exposed to clients, limited │
│ Secret │ Server-side only │
│ Restricted │ Limited to specific endpoints │
│ Rate-limited │ Throttled usage │
└────────────────┴──────────────────────────────────┘

NEVER Store Plain Text Passwords!
=================================
Bad Practice: Best Practice:
────────────── ─────────────
username: john username: john
password: mypass123 password_hash: $2b$12$...
(PLAIN TEXT!) (bcrypt hash)
─────────────────────────────────────────
Attack Scenarios:
1. Database stolen
Plain: All passwords exposed
Hashed: Need to crack
2. Rainbow table attack
Plain: Instant lookup
Hashed: Need salt + slow hash
3. Brute force
Plain: Fast
Hashed: bcrypt is intentionally slow
AlgorithmSpeedGPU ResistantNotes
bcryptSlowModerateMost popular
Argon2ConfigurableYesModern, recommended
scryptSlowYesMemory-hard
PBKDF2SlowModerateWidely supported
# Using bcrypt
import bcrypt
# Hashing
password = "my_secure_password"
salt = bcrypt.gensalt()
hashed = bcrypt.hashpw(password.encode(), salt)
# Verify
bcrypt.checkpw(password.encode(), hashed)
# Result:
# $2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/LewY5GyY8K.x5H9W
# │ │ │
# │ │ └── 31 char hash
# │ └─────── 19 char salt
# └──────────── Work factor (2^12 = 4096 rounds)
Strong Password Policy
====================
✓ Minimum 12 characters
✓ Mix of uppercase and lowercase
✓ Include numbers
✓ Include special characters
✓ No common dictionary words
✓ No personal information
─────────────────────────────────────────
What to NEVER do:
✗ Store plain text passwords
✗ Limit password length
✗ Require frequent changes without reason
✗ Use MD5 or SHA for passwords

MFA Factors
===========
┌─────────────────────────────────────────────────────┐
│ Factor 1: Something you KNOW │
│ ───────────────────────────────────────────────── │
│ • Password │
│ • PIN │
│ • Security questions │
└─────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────┐
│ Factor 2: Something you HAVE │
│ ───────────────────────────────────────────────── │
│ • Phone (SMS/Call) │
│ • Hardware token (YubiKey) │
│ • Authenticator app (TOTP) │
│ • Email │
└─────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────┐
│ Factor 3: Something you ARE │
│ ───────────────────────────────────────────────── │
│ • Fingerprint │
│ • Face recognition │
│ • Voice print │
│ • Retina scan │
└─────────────────────────────────────────────────────┘
# Using pyotp for TOTP
import pyotp
# Setup (store secret in database)
secret = pyotp.random_base32()
totp = pyotp.TOTP(secret)
# User sees this QR code during setup
# scan with authenticator app (Google Auth, Authy, etc.)
# Verify code
code = input("Enter 6-digit code: ")
if totp.verify(code):
print("Authenticated!")
else:
print("Invalid code")

RBAC Model
==========
┌──────────┐ ┌──────────┐ ┌──────────┐
│ User │ │ Role │ │Permission│
│ │ │ │ │ │
│ user-1 │──┐ │ admin │──┐ │ read │
│ user-2 │ │ │ editor │ │ │ write │
│ user-3 │ │ │ viewer │ │ │ delete │
└──────────┘ │ └──────────┘ │ └──────────┘
│ │ │
└─────────┴─────────┘
User → Role → Permission
{
"roles": {
"admin": {
"permissions": ["read", "write", "delete", "manage_users"]
},
"editor": {
"permissions": ["read", "write"]
},
"viewer": {
"permissions": ["read"]
}
},
"users": {
"user-1": ["admin"],
"user-2": ["editor"],
"user-3": ["viewer"]
}
}

18.5.2 ABAC (Attribute-Based Access Control)

Section titled “18.5.2 ABAC (Attribute-Based Access Control)”
{
"policy": {
"effect": "allow",
"actions": ["read", "write"],
"resource": "/documents/*",
"conditions": {
"and": [
{"resource.owner": {"equals": "request.user.id"}},
{"time": {"greaterThan": "09:00", "lessThan": "17:00"}},
{"request.ip": {"in": ["10.0.0.0/8", "192.168.0.0/16"]}}
]
}
}
}
OAuth Scopes
===========
Request:
GET /oauth/authorize?
client_id=myapp&
redirect_uri=https://myapp.com/callback&
response_type=code&
scope=read:profile write:profile delete:profile
─────────────────────────────────────────
Available Scopes:
┌────────────────────┬─────────────────────────────────┐
│ Scope │ Description │
├────────────────────┼─────────────────────────────────┤
│ read:profile │ Read user profile │
│ write:profile │ Update user profile │
│ read:email │ Read email address │
│ read:contacts │ Read contacts │
│ publish │ Publish content │
└────────────────────┴─────────────────────────────────┘

Authentication Security Checklist
================================
✓ Always use HTTPS
✓ Use strong password hashing (bcrypt/Argon2)
✓ Implement rate limiting on login
✓ Add CAPTCHA for repeated failures
✓ Use MFA for sensitive accounts
✓ Implement session timeout
✓ Use secure cookies (HttpOnly, Secure, SameSite)
✓ Rotate sessions after authentication
✓ Log authentication attempts
✓ Implement account lockout
✓ Use secure password reset flow
─────────────────────────────────────────
Token Security Checklist
=========================
✓ Use short-lived access tokens (15-60 min)
✓ Use refresh tokens for persistence
✓ Store tokens securely (not localStorage for sensitive)
✓ Implement token revocation
✓ Use signed tokens (JWT with RS256)
✓ Validate all claims (iss, aud, exp)
─────────────────────────────────────────
API Security Checklist
=======================
✓ Use API keys for server-to-server
✓ Implement rate limiting
✓ Use IP allowlisting
✓ Monitor for abuse patterns
✓ Rotate API keys regularly

  1. Authentication verifies identity (WHO you are)
  2. Authorization controls access (WHAT you can do)
  3. Sessions - Traditional, server-stored state
  4. JWT - Stateless, client-stored tokens
  5. OAuth 2.0 - Delegated authorization
  6. MFA - Multiple authentication factors
  7. Password security - Always hash, never store plain text
  8. RBAC/ABAC - Authorization models

Next: Chapter 19: Message Queues & Event Streaming