Security

Session & Token Management

Intermediate

A token carries trust: whoever holds it is treated as the user it represents. So how you issue, validate, scope, store, and revoke tokens is one of the most important security decisions in the system. A weak token scheme undoes every careful authorisation check behind it.

Sessions and tokens are where authentication becomes ongoing authorisation. The questions that matter are concrete. Is this token really ours and unchanged? Is it still valid? What exactly does it allow? Where is it stored on the client? And when something goes wrong, can we revoke it fast? Answer those on purpose, and most session attacks have nowhere to land.

The Finperiti sample's symmetric HS256 tokens show the issuance risk: a shared secret means anyone who can verify a token can forge one. But even with strong signing, careless validation, poor storage, or no way to revoke will still sink you.

Issue & validate rigorously

Partial validation var jwt = handler.ReadJwtToken(raw);
var role = jwt.Claims.First(c => c.Type == "role").Value;

This reads claims without validating the signature, issuer, audience, or expiry. An attacker can hand you any claims they like. Always validate before reading.

Validate, then trust var result = await handler.ValidateTokenAsync(raw, validationParams);
if (!result.IsValid) return Unauthorized();
var role = result.ClaimsIdentity.FindFirst("role")?.Value;

Claims are only consulted after full validation against the configured signing keys, issuer, audience, and lifetime.

Store, scope & revoke

Self-review checklist

Why it matters: A token is portable trust. A single weakness in issuance, validation, or storage lets an attacker become a real user and bypass every control behind it. Short lifetimes, strong validation, tight scope, and fast revocation are what keep a stolen token from becoming a stolen account.