Saltar al contenido
Esta página aún no está traducida.

IJwtReplayCache Interface

Tracks JWT IDs (jti claims) presented to the server, so a JWT-bearing flow can detect replay attempts. Both RFC 7523 §3 (JWT-bearer-grant assertion replay) and RFC 9449 §11.1 (DPoP proof replay) want this primitive; it is intentionally namespace-neutral so a single distributed-cache instance serves every consumer.

C#
public interface IJwtReplayCache

Derived
↳ DistributedJwtReplayCache

Remarks

The primitive now lives in Abblix.JWT as IReplayCache, one layer below this package, because Security Event Token receivers need the same reserve-and-check and cannot reference the OpenID Connect server to get it. This contract remains registered and working for host code that names it, and its default implementation stores through the moved one, so both spellings share a single set of entries.

Methods

IJwtReplayCache.TryAddAsync(string, Nullable<DateTimeOffset>) Method

Records a fresh jti, returning true only on the first call for that value. The single-call shape is atomic-by-contract: implementations are expected to use the backend's compare-and-set primitive so concurrent presenters of the same jti cannot both observe a miss and both succeed.

C#
System.Threading.Tasks.Task<bool> TryAddAsync(string jti, System.Nullable<System.DateTimeOffset> expiresAt);

Parameters

jti System.String

The JWT ID (jti claim) to record.

expiresAt System.Nullable<System.DateTimeOffset>

Latest moment a same-jti replay could still pass the iat-window check; the cache entry only needs to persist that long. null defers to the implementation's default TTL.

Returns

System.Threading.Tasks.Task<System.Boolean>
true if the jti was newly recorded (proof is fresh); false if it was already present (replay detected).

Remarks

Atomic-capable backends close the race natively: Redis SET ... NX EX (via StackExchange.Redis), SQL INSERT ... ON CONFLICT DO NOTHING, Memcached add, in-memory ConcurrentDictionary.TryAdd.

The default implementation DistributedJwtReplayCache uses Microsoft.Extensions.Caching.Distributed.IDistributedCache, which exposes only Get + Set and no compare-and-set primitive. It therefore provides only a probabilistic guarantee: two concurrent presenters of the same jti can both observe a miss before either writes. The race window is bounded by the cache round-trip and RFC 9449 §11.1 accepts probabilistic replay defence - but hosts that need strict atomicity should override the registration with a backend-aware implementation that bypasses Microsoft.Extensions.Caching.Distributed.IDistributedCache and talks to the chosen backend's atomic primitive directly.