Class DapperServerSideSessionStore
- Namespace
- Fdyay.IdentityServer.Dapper.Stores
- Assembly
- Fdyay.IdentityServer.Dapper.dll
Dapper-backed server-side session store.
public sealed class DapperServerSideSessionStore : IServerSideSessionStore
- Inheritance
-
DapperServerSideSessionStore
- Implements
- Inherited Members
Remarks
The in-memory store is development-only, and the two ways it falls short are both invisible in development: sessions do not survive a restart, so every deploy signs everyone out, and they are not shared between instances, so the ticket key in the cookie resolves on the instance that wrote it and nowhere else. The second presents as users being signed out intermittently, whenever the load balancer moves them, which is the worst way for it to present. This is the store that makes server-side sessions usable in production.
Constructors
DapperServerSideSessionStore(IDbConnectionFactory)
Creates a session store over the ServerSideSessions table, on the system clock.
public DapperServerSideSessionStore(IDbConnectionFactory connectionFactory)
Parameters
connectionFactoryIDbConnectionFactoryOpens a connection for each operation and supplies the dialect's upsert and paging clause.
DapperServerSideSessionStore(IDbConnectionFactory, TimeProvider)
Creates a session store over the ServerSideSessions table, on the server's clock.
public DapperServerSideSessionStore(IDbConnectionFactory connectionFactory, TimeProvider time)
Parameters
connectionFactoryIDbConnectionFactoryOpens a connection for each operation and supplies the dialect's upsert and paging clause.
timeTimeProviderThe clock the expiry sweep judges
Expiresagainst — the server's, as every other store here reads.
Remarks
Since 0.175.0, and the one the container builds; until then the sweep read UtcNow.
Methods
CreateSessionAsync(ServerSideSession, CancellationToken)
Stores a session under its Key, replacing any already held under that key.
public Task CreateSessionAsync(ServerSideSession session, CancellationToken cancellationToken = default)
Parameters
sessionServerSideSessionThe session.
cancellationTokenCancellationTokenCancels the write.
Returns
Remarks
An upsert rather than an insert, because that is what the in-memory store does. Two implementations of one interface that disagree about a re-used key disagree only in production, where the store is not the in-memory one.
DeleteSessionAsync(string, CancellationToken)
Removes the session stored under a key. A key with nothing stored under it is not an error.
public Task DeleteSessionAsync(string key, CancellationToken cancellationToken = default)
Parameters
keystringThe session's Key.
cancellationTokenCancellationTokenCancels the removal.
Returns
Remarks
Deletes the ServerSideSessions row whose SessionKey matches. A miss deletes nothing and is not an error.
Exceptions
- ArgumentException
keyis null or empty.
DeleteSessionsAsync(SessionFilter, CancellationToken)
Ends every session matching the filter.
public Task DeleteSessionsAsync(SessionFilter filter, CancellationToken cancellationToken = default)
Parameters
filterSessionFiltercancellationTokenCancellationToken
Returns
Remarks
Deletes the ServerSideSessions rows matching the filter's subject id and session id, whichever it sets.
No match deletes nothing and is not an error.
Exceptions
- ArgumentNullException
filteris null.- ArgumentException
filternames neither a subject nor a session, which would otherwise end every session.
GetAndRemoveExpiredSessionsAsync(int, CancellationToken)
Removes sessions past their expiry and returns them, so a caller can act on what it removed.
public Task<IReadOnlyCollection<ServerSideSession>> GetAndRemoveExpiredSessionsAsync(int count, CancellationToken cancellationToken = default)
Parameters
countintcancellationTokenCancellationToken
Returns
Remarks
Returns rather than merely deletes because an expired session still has clients that were signed in to it, and they are owed a back-channel logout. A sweep that deleted silently would leave every relying party believing a session that ended hours ago is still live.
GetSessionAsync(string, CancellationToken)
The session stored under a key, or null.
public Task<ServerSideSession?> GetSessionAsync(string key, CancellationToken cancellationToken = default)
Parameters
keystringThe session's Key.
cancellationTokenCancellationTokenCancels the read.
Returns
- Task<ServerSideSession>
The session, or null when none is stored under that key.
Remarks
Reads the ServerSideSessions row whose SessionKey matches. A miss returns null; an expired row is
returned as stored, for the caller to judge.
Exceptions
- ArgumentException
keyis null or empty.
GetSessionsAsync(SessionFilter, CancellationToken)
Every session matching the filter.
public Task<IReadOnlyCollection<ServerSideSession>> GetSessionsAsync(SessionFilter filter, CancellationToken cancellationToken = default)
Parameters
filterSessionFiltercancellationTokenCancellationToken
Returns
Remarks
Reads the ServerSideSessions rows matching the filter's subject id and session id, whichever it sets,
expired ones included. No match is an empty collection.
Exceptions
- ArgumentNullException
filteris null.- ArgumentException
filternames neither a subject nor a session.
QuerySessionsAsync(SessionQuery, CancellationToken)
A page of sessions, for an administrative list.
public Task<QueryResult<ServerSideSession>> QuerySessionsAsync(SessionQuery query, CancellationToken cancellationToken = default)
Parameters
querySessionQuerycancellationTokenCancellationToken
Returns
Remarks
Counts and then pages the ServerSideSessions rows, filtered when Filter is set
and ordered by Created then SessionKey. A page or page size below one is treated as one. A page past
the end returns no results alongside the true total.
Exceptions
- ArgumentNullException
queryis null.
UpdateSessionAsync(ServerSideSession, CancellationToken)
Replaces the session stored under its Key, or stores it when none is.
public Task UpdateSessionAsync(ServerSideSession session, CancellationToken cancellationToken = default)
Parameters
sessionServerSideSessionThe session as it now stands.
cancellationTokenCancellationTokenCancels the write.
Returns
Remarks
Also an upsert, and deliberately not an UPDATE that no-ops on a missing row. The guard against
resurrecting a revoked session lives in ServerSideTicketStore.RenewAsync, which reads before it
writes; putting a second, differently-shaped guard here would make the two stores disagree about what
updating an absent key means.