Blog
Mert Özen's blog posts on software development, backend, frontend, and DevOps.
Mapping Authentication and Authorization: Credentials, Sessions, Tokens, Claims and ASP.NET Core's Authentication Handler Model
Authentication finds out who you are, authorization decides what you may do; in ASP.NET Core the first fills HttpContext.User through named schemes and handlers, the second checks policies and calls challenge (401) or forbid (403). We name credentials, sessions, tokens and claims, combine cookies and JWT with a policy scheme, and show why an endpoint returning Results.Ok still answers 302 on .NET 10.
ASP.NET Core Cookie Authentication in Depth: Session Lifetime, Sliding Expiration, Server-Side Sessions and Revocation
Sliding expiration alone can keep a session alive forever; you have to add an absolute timeout yourself with OnValidatePrincipal, and revocation needs state on the server (ITicketStore or a version stamp). We show the cookie ticket's contents, the 14-day default, renewal at half the window, chunking, server-side sessions in Redis and signing out of all devices with real outputs.
The Architecture of ASP.NET Core Identity: UserManager, SignInManager, Stores and Customization
ASP.NET Core Identity is not a single login system; UserManager runs user rules, SignInManager the HTTP session and store interfaces the data access, in separate layers. We build our own user entity with Guid keys and table names, and examine schema versions, the four registration methods and MapIdentityApi's non-JWT token and reusable refresh token with real outputs.
The Account Lifecycle with ASP.NET Core Identity: Registration, Email Confirmation, Password Reset, External Login and Account Deletion
Identity's reset token is never marked as used; it carries the security stamp, so it dies when the password changes, and its default lifetime is one day. We build registration, e-mail confirmation, a password reset provider with its own lifetime, dropping other sessions, e-mail change, the risk of automatic linking in Google external login, and personal data export and account deletion for KVKK/GDPR, with an Angular screen.
MFA: TOTP, Recovery Codes, Step-up Authentication and the Weakness of SMS
ASP.NET Core Identity's default authenticator provider accepts a TOTP code within ±2 time steps (five codes) and again and again, while NIST requires a code to be accepted once. We compute TOTP ourselves against the RFC 6238 test vector and show setup, lockout, a replay-protected provider, recovery codes, a step-up policy with the amr claim and the risks of SMS and 'remember this device' with real outputs.
Passkeys 1: How WebAuthn and FIDO2 Work: RP ID, Challenge, Attestation and Assertion
A passkey resists phishing because the browser uses the credential only on origins of its registered RP ID, and the signature covers the clientDataJSON that carries the origin and the challenge. We decode real attestation and assertion data captured in the Bookstore lab with CBOR, verify the signature by hand, and explain the UV, BE and BS flags, synced versus device-bound passkeys and account recovery design.
Passkeys 2: Passkey Registration and Passwordless Sign-in with ASP.NET Core Identity 10 and an Angular Client
ASP.NET Core Identity 10 ships passkey registration and passwordless sign-in through SignInManager's MakePasskeyCreationOptionsAsync, PerformPasskeyAttestationAsync and PasskeySignInAsync; but with an empty ServerDomain the RP ID comes from the Host header, and a passkey sign-in writes pwd as amr. We build the Angular client, conditional UI and an end-to-end test with headless Chrome's virtual authenticator.
JWT in Depth: JWS and JWE, Algorithm Choice, kid, JWKS and Signing Key Rotation
Seamless signing key rotation takes three steps: publish the new key in the JWKS, wait until the APIs' caches refresh (12 hours by default), then sign with it and retire the old key once token lifetimes pass. We show JWS versus JWE, choosing ES256, alg none and algorithm confusion attempts, typ validation with at+jwt, kid and JWKS, the 8725bis draft's warnings and claim bloat with real outputs.
Refresh Tokens: Rotation, Reuse Detection, Revocation and Secure Server-Side Storage
A refresh token should be replaced on every use, and if a consumed token comes back, the whole token family of that sign-in should be revoked; RFC 9700 requires this or sender-constrained tokens for public clients. With EF Core and SQLite we build SHA-256 hashed storage, atomic consumption with ExecuteUpdate, reuse detection, the two-tab race, sliding and absolute lifetimes and signing out of all devices with real outputs.
The Logic of OAuth 2.0: Roles, Grant Types, Scopes and What RFC 9700 and OAuth 2.1 Bring
OAuth 2.0 is a delegation protocol, not a sign-in protocol. We run the four roles, the front/back channel split, confidential vs public clients, and the authorization code, client credentials and device grants against a Keycloak lab with .NET 10 code; then show why implicit and password grants were removed, what RFC 9700 and the OAuth 2.1 draft bring, and why an access token is not proof of sign-in.
Authorization Code Flow + PKCE Step by Step: state, nonce, PAR and Reading the HTTP Traffic with Keycloak
PKCE binds the code that crosses the front channel to the client that asked for it; a stolen code is useless without the verifier. In a Keycloak lab we read the flow step by step with curl, show what state and nonce prevent, that a code is burned after a wrong verifier and why redirect URIs must match exactly; then we move parameters to the back channel with PAR and trace ASP.NET Core's OIDC handler end to end.
OpenID Connect: ID Tokens, UserInfo, Discovery, AddOpenIdConnect in ASP.NET Core and Logout Types
An ID token is a sign-in record written for the client, an access token is a permission written for the API; mixing them up is a vulnerability. In a Keycloak lab we read discovery, JWKS and UserInfo, show how MapInboundClaims renames claims in AddOpenIdConnect, trace RP-initiated logout, and write a back-channel logout endpoint that drops this app's cookie when the user signs out of another app.