Modern identity systems handle authentication (who are you?) and authorization (what can you do?). OAuth2 and OIDC are the web standards. SAML is the enterprise standard. Kerberos is the network standard. FreeIPA combines LDAP, Kerberos, and DNS for Linux environments.
| Item | Syntax / Value | Description |
|---|---|---|
| Authentication | Verify identity — who are you? | Password, certificate, biometric, token |
| Authorization | What actions are permitted? | Roles, permissions, policies |
| SSO | Single Sign-On — one login, many apps | Log in once to Okta/AD, access all services |
| OAuth2 | Authorization framework — delegate access | 'Login with Google' — app gets token, not password |
| OAuth2 flows | Authorization Code, Client Credentials, Device | Authorization Code = web apps, Client Credentials = M2M |
| OIDC | OpenID Connect — identity layer on top of OAuth2 | OAuth2 + ID token (JWT with user info) |
| JWT | JSON Web Token — signed token with claims | Header.Payload.Signature — stateless auth |
| JWT structure | eyJhbGci.eyJzdWIi.signature | Base64url(header).Base64url(payload).signature |
| JWT claims | sub, iss, aud, exp, iat, nbf, jti | sub=subject, exp=expiry, iss=issuer |
| JWT verify | Check signature + exp + iss + aud | Never trust JWT without signature verification! |
| Bearer token | Authorization: Bearer <jwt> | JWT sent in Authorization header |
| Refresh token | Long-lived token to get new access tokens | Access token expires fast (15min), refresh = hours/days |
| SAML | Security Assertion Markup Language — XML-based SSO | Enterprise SSO: Okta, ADFS, Shibboleth |
| SAML SP | Service Provider — the application | Redirects to IdP for authentication |
| SAML IdP | Identity Provider — authenticates users | AD FS, Okta, OneLogin, Azure AD |
| SAML assertion | XML document proving identity | Contains attributes: email, name, groups |
| MFA | Multi-Factor Authentication | Something you know + have + are |
| TOTP | Time-based One-Time Password — RFC 6238 | Google Authenticator, Authy — 6-digit code changes every 30s |
| FIDO2/WebAuthn | Hardware security key authentication | YubiKey, Windows Hello, Touch ID — phishing resistant |
| RBAC | Role-Based Access Control | Roles: admin, editor, viewer — assign to users |
| ABAC | Attribute-Based Access Control | Policies based on user attributes, resource, environment |
| Kerberos | Network authentication protocol — tickets | Active Directory uses Kerberos internally |
| KDC | Key Distribution Center | Kerberos server: Authentication Server + Ticket Granting Server |
| TGT | Ticket Granting Ticket — proves identity to KDC | kinit alice@EXAMPLE.COM — get TGT |
| Service ticket | Ticket for specific service — from TGS | klist shows current tickets |
| FreeIPA | Red Hat's identity management — LDAP+Kerberos+DNS | Integrated IdM for Linux/UNIX environments |
| Okta / Azure AD | Cloud identity providers | Enterprise SSO, MFA, lifecycle management |
| PAM | Pluggable Authentication Modules | Linux authentication framework — pam_krb5, pam_ldap |
# ── JWT — Generate and Verify (Python) ───────────────────────
# pip install pyjwt cryptography
import jwt
import datetime
import secrets
SECRET_KEY = secrets.token_hex(32) # In production: load from secrets manager!
# Generate JWT (access token)
def create_token(user_id: str, email: str, roles: list, expires_minutes: int = 15):
now = datetime.datetime.utcnow()
payload = {
'sub': user_id, # subject
'email': email,
'roles': roles,
'iss': 'https://auth.mywebuniversity.com', # issuer
'aud': 'https://api.mywebuniversity.com', # audience
'iat': now, # issued at
'exp': now + datetime.timedelta(minutes=expires_minutes), # expiry
'jti': secrets.token_hex(16), # JWT ID (unique)
}
return jwt.encode(payload, SECRET_KEY, algorithm='HS256')
# Verify JWT
def verify_token(token: str) -> dict:
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=['HS256'],
audience='https://api.mywebuniversity.com')
return payload
except jwt.ExpiredSignatureError:
raise ValueError("Token has expired")
except jwt.InvalidTokenError as e:
raise ValueError(f"Invalid token: {e}")
# Usage
token = create_token("usr_1001", "alice@mywebuniversity.com", ["student", "editor"])
print(f"Token: {token[:40]}...")
payload = verify_token(token)
print(f"User: {payload['email']}")
print(f"Roles: {payload['roles']}")
print(f"Expires: {datetime.datetime.fromtimestamp(payload['exp'])}")
# ── OAuth2 Authorization Code Flow ───────────────────────────
# Step 1: Redirect user to provider
import urllib.parse
params = {
'client_id': 'mywebuniversity-client-id',
'redirect_uri': 'https://www.mywebuniversity.com/auth/callback',
'response_type': 'code',
'scope': 'openid email profile',
'state': secrets.token_urlsafe(16), # CSRF protection
'nonce': secrets.token_urlsafe(16), # Replay protection
}
auth_url = 'https://accounts.google.com/o/oauth2/v2/auth?' + urllib.parse.urlencode(params)
print(f"Redirect to: {auth_url[:80]}...")
# Step 2: Exchange code for tokens (server-side)
import requests
def exchange_code(code: str, state: str, expected_state: str) -> dict:
if state != expected_state:
raise ValueError("State mismatch — possible CSRF attack!")
resp = requests.post('https://oauth2.googleapis.com/token', data={
'code': code,
'client_id': 'mywebuniversity-client-id',
'client_secret': 'client-secret-from-google-console',
'redirect_uri': 'https://www.mywebuniversity.com/auth/callback',
'grant_type': 'authorization_code',
})
return resp.json() # access_token, id_token, refresh_token
# ── Kerberos ──────────────────────────────────────────────────
# Get Kerberos ticket (authenticate)
kinit alice@MYWEBUNIVERSITY.COM
# Enter password — get TGT valid for 24 hours
# List current tickets
klist
# Krb5 Credentials Cache: KEYRING:persistent:1000
# Default principal: alice@MYWEBUNIVERSITY.COM
# Valid starting Expires Service principal
# 06/27/2026 08:00 06/28/2026 08:00 krbtgt/MYWEBUNIVERSITY.COM
# Use with curl (GSSAPI/Negotiate authentication)
curl --negotiate -u : https://kerberized-app.mywebuniversity.com/
# Destroy ticket
kdestroy
# ── FreeIPA ───────────────────────────────────────────────────
# Install IPA client on Linux
sudo apt install freeipa-client
sudo ipa-client-install --domain=mywebuniversity.com \
--server=ipa.mywebuniversity.com \
--principal=admin --password=adminpass
# IPA commands (on IPA server)
ipa user-add alice --first=Alice --last=Smith --email=alice@mywebuniversity.com
ipa user-mod alice --title="Senior Developer"
ipa group-add developers --desc="Development team"
ipa group-add-member developers --users=alice,bob
ipa user-find --login=alice
ipa hbacrule-add allow_ssh_to_webservers --usercat=all --hostcat=all
ipa hbacrule-add-service allow_ssh_to_webservers --hbacsvcs=ssh