DistributedReplayCache Class
A replay cache over the host's Microsoft.Extensions.Caching.Distributed.IDistributedCache: process-local when the host registers the in-memory distributed cache, shared when it registers Redis or another backend - so a scaled-out deployment gains one common memory by swapping the store, not the cache.
public sealed class DistributedReplayCache : Abblix.Jwt.ReplayPrevention.ReplayCacheBaseInheritance System.Object → ReplayCacheBase → DistributedReplayCache
Remarks
The add-if-absent underneath is probabilistic, not strict: two concurrent presenters of one identifier can both hear "new" within a single cache round trip, because Microsoft.Extensions.Caching.Distributed.IDistributedCache offers Get and Set and no compare-and-set. Each profile decides whether that is acceptable - RFC 9449 Section 11.1 accepts probabilistic replay defence for DPoP proofs, and RFC 8935 Section 2 lets a transmitter redeliver a SET regardless, so a lost race costs one duplicate idempotent pass. A client assertion is the one that does not read that way, since RFC 7523 Section 3 lets an authorization server reject a reused one. A deployment relying on that rejection takes a ReplayCacheBase over a store that decides and writes in one operation.
Constructors
DistributedReplayCache(IDistributedCache, TimeProvider, string) Constructor
A replay cache over the host's Microsoft.Extensions.Caching.Distributed.IDistributedCache: process-local when the host registers the in-memory distributed cache, shared when it registers Redis or another backend - so a scaled-out deployment gains one common memory by swapping the store, not the cache.
public DistributedReplayCache(Microsoft.Extensions.Caching.Distributed.IDistributedCache cache, System.TimeProvider clock, string keyPrefix);Parameters
cache Microsoft.Extensions.Caching.Distributed.IDistributedCache
The distributed cache the host registered; the store is the host's choice.
clock System.TimeProvider
The clock the retention window is measured against.
keyPrefix System.String
Keeps these entries out of the way of whatever else shares the host's cache. It is the caller's to choose and its exact text is a deployment contract, not an implementation detail: entries written under one prefix are invisible under another, so changing it mid-rollout leaves the identifiers already reserved unreachable until they age out.
Remarks
The add-if-absent underneath is probabilistic, not strict: two concurrent presenters of one identifier can both hear "new" within a single cache round trip, because Microsoft.Extensions.Caching.Distributed.IDistributedCache offers Get and Set and no compare-and-set. Each profile decides whether that is acceptable - RFC 9449 Section 11.1 accepts probabilistic replay defence for DPoP proofs, and RFC 8935 Section 2 lets a transmitter redeliver a SET regardless, so a lost race costs one duplicate idempotent pass. A client assertion is the one that does not read that way, since RFC 7523 Section 3 lets an authorization server reject a reused one. A deployment relying on that rejection takes a ReplayCacheBase over a store that decides and writes in one operation.