Table of Contents

Class TokenCleanup

Namespace
Fdyay.IdentityServer.Dapper
Assembly
Fdyay.IdentityServer.Dapper.dll

Deletes persisted grants that can no longer be redeemed.

public sealed class TokenCleanup
Inheritance
TokenCleanup
Inherited Members

Remarks

Nothing removes a grant when it expires: authorization codes, refresh tokens, reference tokens and consent are written on issue and deleted only when they are used. A server that is never swept therefore accumulates a row for every token it has ever issued, and the table grows without limit — which is a storage bill and, eventually, an index that no longer fits the queries the store depends on.

Constructors

TokenCleanup(IDbConnectionFactory, TimeProvider)

Creates a sweeper over the tables connectionFactory reaches.

public TokenCleanup(IDbConnectionFactory connectionFactory, TimeProvider time)

Parameters

connectionFactory IDbConnectionFactory

Opens a connection for each sweep.

time TimeProvider

The clock that decides what counts as expired.

Methods

RemoveExpiredBackChannelAuthenticationRequestsAsync(CancellationToken)

Removes backchannel authentication requests past their expiry.

public Task<int> RemoveExpiredBackChannelAuthenticationRequestsAsync(CancellationToken cancellationToken = default)

Parameters

cancellationToken CancellationToken

Returns

Task<int>

Remarks

The same housekeeping the device codes need and for a sharper reason: a CIBA request reaches a person only if they happen to visit an approval surface while it is still alive, so the ones nobody ever answers are the common case rather than the exception. Answered requests are removed by the grant path when the tokens are collected; these are the ones that were never answered at all.

Expiry only, and never completion. A completed request whose client has not yet polled is still owed its answer, and deleting it here would turn a successful approval into a client waiting out its lifetime for a request that no longer exists.

RemoveExpiredDeviceCodesAsync(CancellationToken)

Removes device authorizations past their expiry.

public Task<int> RemoveExpiredDeviceCodesAsync(CancellationToken cancellationToken = default)

Parameters

cancellationToken CancellationToken

Returns

Task<int>

Remarks

The store already treats an expired row as absent, so this is housekeeping rather than correctness. Most device authorizations are never approved and never redeemed — a device shows a code and the user walks away — so without a sweep the table only grows.

RemoveExpiredGrantsAsync(bool, CancellationToken)

Removes grants past their expiry, and optionally those already consumed.

public Task<int> RemoveExpiredGrantsAsync(bool removeConsumedTokens = false, CancellationToken cancellationToken = default)

Parameters

removeConsumedTokens bool
cancellationToken CancellationToken

Returns

Task<int>

Remarks

Expressed as deletes over a predicate rather than a read-then-delete, so two instances sweeping at the same moment simply delete the same rows once. There is no coordination to get wrong and no leader to elect: running this on every instance is safe.

RemoveExpiredPushedRequestsAsync(CancellationToken)

Removes pushed authorization requests past their expiry.

public Task<int> RemoveExpiredPushedRequestsAsync(CancellationToken cancellationToken = default)

Parameters

cancellationToken CancellationToken

Returns

Task<int>

Remarks

A pushed request that is never redeemed — the client pushed it and the user closed the tab — is otherwise never removed, and pushing is cheap enough that a busy client leaves a great many of them behind.