From 4c0f3a408024d1b820903602087f7556f9f3baf0 Mon Sep 17 00:00:00 2001 From: James Britton Date: Wed, 9 Sep 2026 13:53:17 +0100 Subject: [PATCH 1/3] docs: adding docs for implemented so far features of server side sessions --- docs/index.rst | 1 + docs/reference/options.rst | 21 +++++++ docs/topics/server_side_sessions.rst | 83 ++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+) create mode 100644 docs/topics/server_side_sessions.rst diff --git a/docs/index.rst b/docs/index.rst index 273c959de..f6587511f 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -80,6 +80,7 @@ Open.IdentityServer enables the following features in your applications: topics/compatibility topics/resources topics/clients + topics/server_side_sessions topics/signin topics/signin_external_providers topics/windows diff --git a/docs/reference/options.rst b/docs/reference/options.rst index 040115b8d..5b537d0e1 100644 --- a/docs/reference/options.rst +++ b/docs/reference/options.rst @@ -155,3 +155,24 @@ Mutual TLS Specifies whether a cnf claim gets emitted for access tokens if a client certificate was present. Normally the cnf claims only gets emitted if the client used the client certificate for authentication, setting this to true, will set the claim regardless of the authentication method. (defaults to false). + +Server-Side Sessions +^^^^^^^^^^^^^^^^^^^^ + +* ``ExpiredSessionsTriggerBackchannelLogout`` + Specifies if session expiry should trigger back channel logout, this will override any other settings that may + cause back channel logout such as AuthenticationOptions.CoordinateClientLifetimesWithUserSession or + Client.CoordinateLifetimeWithUserSession. + +* ``RemoveExpiredSessions`` + Specifies if expired sessions should be cleaned up automatically by Open.IdentityServer. The default value is true. + +* ``RemoveExpiredSessionsFrequency`` + Specifies the frequency with which expired sessions are looked for and removed. The default value is a TimeSpan of 10 minutes. + +* ``FuzzExpiredSessionsFrequency`` + Specifies if the start time of the hosted service should be randomised to avoid limiting the occurrences of jobs + running simultaneously in scenarios with multiple instances of Open.IdentityServer are running. The default value is true. + +* ``RemoveExpiredSessionsBatchSize`` + Specifies how many expired sessions should be removed in a single pass. The default value is 100. diff --git a/docs/topics/server_side_sessions.rst b/docs/topics/server_side_sessions.rst new file mode 100644 index 000000000..ae222a94a --- /dev/null +++ b/docs/topics/server_side_sessions.rst @@ -0,0 +1,83 @@ +.. _refServerSideSessions: + +Server-Side Sessions +==================== + +Overview +-------- +When users authenticate with Open.IdentityServer, a session is created to track the logged in user. By default this will be done +storing this state in cookies in the user browser. This approach of storing session state in a cookie can work well for many scenarios +but does have some drawbacks. + +* **No Tracking Active Sessions** - There is no way to track active sessions, and how many users are currently logged in. +* **No Immidiate Revokation** - There will be no process of immidiate session revokation on the serevr ad a session cookie will be valid till it expires, or they log out. +* **No Sign-Out Coordination** - Coordinating sign-outs from Open.IdentityServer with connected clients is less relable without server tracking of active sessions. + +Open.IdentityServer Server-Side Sessions solves these issues by storing the contents of this cookie in a server side data store. This enables +in Open.IdentityServer the ability to: + +* Provide APIs for manging and querying active user sessions +* Support for explicit session revokation regardless of the cookie state in the browser +* Storing session data server side, so browser cookie only contains an ID for the session nothing more + +Getting Started +^^^^^^^^^^^^^^^ + +1. **Database schema** + + Ensure your database is in the correct state. If you are coming from Duende + IdentityServer, there is nothing further to do - the schema is already compatible. + If you are migrating from IdentityServer4 and have not yet updated your schema to + match the Open.IdentityServer schema, you will need to do this first. See + :ref:`migration from IdentityServer4 ` for details. + +2. **Enable server-side sessions** + + Call ``.AddServerSideSessions()`` when configuring Open.IdentityServer: + + .. code-block:: csharp + + builder.Services.AddIdentityServer() + .AddServerSideSessions(); + +3. **Configure a session store** + + ``AddServerSideSessions`` requires an implementation of ``IServerSideSessionStore`` + to persist session data. If you are using Entity Framework Core, this is provided + automatically when you configure the operational store: + + .. code-block:: csharp + + builder.Services.AddIdentityServer() + .AddServerSideSessions() + .AddOperationalStore(options => + { + options.ConfigureDbContext = b => + b.UseSqlServer("ConnectionString"); + }); + + If you are not using the built-in EF Core store, you will need to provide your own + ``IServerSideSessionStore`` implementation. + +5. **(Optional) Configure additional session options** + + You can customize behavior via ``ServerSideSessionOptions``, such as how often + sessions are checked for expiration in the background, or coordinating this with + your sign-in cookie expiration: + + .. code-block:: csharp + + builder.Services.AddIdentityServer(options => + { + // Other options... + options.ServerSideSessions.ExpiredSessionsTriggerBackchannelLogout = true; + options.ServerSideSessions.RemoveExpiredSessions = true; + options.ServerSideSessions.RemoveExpiredSessionsFrequency = TimeSpan.FromSeconds(10); + options.ServerSideSessions.FuzzExpiredSessionsFrequency = true; + options.ServerSideSessions.RemoveExpiredSessionsBatchSize = 100; + }); + +Managemet Interface +^^^^^^^^^^^^^^^^^^^ + +TODO: not yet implemented \ No newline at end of file From d5754445e40b1e717418c73e0dd351bfc0859165 Mon Sep 17 00:00:00 2001 From: James Britton Date: Mon, 14 Sep 2026 11:41:44 +0100 Subject: [PATCH 2/3] pr: updated after review --- docs/migrating/from_duende.rst | 2 -- docs/reference/options.rst | 4 ++-- docs/topics/server_side_sessions.rst | 30 +++++++++------------------- 3 files changed, 11 insertions(+), 25 deletions(-) diff --git a/docs/migrating/from_duende.rst b/docs/migrating/from_duende.rst index 6a9f7b64d..90e4a7d75 100644 --- a/docs/migrating/from_duende.rst +++ b/docs/migrating/from_duende.rst @@ -71,8 +71,6 @@ Migration Steps - Remove all references. Not yet supported in Open.IdentityServer. * - Automatic Key Management - Remove all references. You will need to configure signing keys manually, or :ref:`configure read-only key store `. - * - Server Side Sessions - - Remove all references. Not yet supported in Open.IdentityServer. * - Pushed Authorisation Requests (PAR) - Remove all references. Not yet supported in Open.IdentityServer. * - CIBA (Client Initiated Backchannel Authentication) diff --git a/docs/reference/options.rst b/docs/reference/options.rst index 5b537d0e1..a3bdbe8cf 100644 --- a/docs/reference/options.rst +++ b/docs/reference/options.rst @@ -171,8 +171,8 @@ Server-Side Sessions Specifies the frequency with which expired sessions are looked for and removed. The default value is a TimeSpan of 10 minutes. * ``FuzzExpiredSessionsFrequency`` - Specifies if the start time of the hosted service should be randomised to avoid limiting the occurrences of jobs - running simultaneously in scenarios with multiple instances of Open.IdentityServer are running. The default value is true. + Specifies if the start time of the hosted service should be randomised. This avoids the scenario where multiple running instances + of identityserver run cleanup jobs simultaneously. The default value is true. * ``RemoveExpiredSessionsBatchSize`` Specifies how many expired sessions should be removed in a single pass. The default value is 100. diff --git a/docs/topics/server_side_sessions.rst b/docs/topics/server_side_sessions.rst index ae222a94a..c6838c833 100644 --- a/docs/topics/server_side_sessions.rst +++ b/docs/topics/server_side_sessions.rst @@ -5,19 +5,16 @@ Server-Side Sessions Overview -------- -When users authenticate with Open.IdentityServer, a session is created to track the logged in user. By default this will be done -storing this state in cookies in the user browser. This approach of storing session state in a cookie can work well for many scenarios -but does have some drawbacks. +When users authenticate with Open.IdentityServer, a session is created to track the logged in user. By default this will be done by storing this state in cookies in the user browser. This approach of storing session state in a cookie can work well for many scenarios but does have some drawbacks. * **No Tracking Active Sessions** - There is no way to track active sessions, and how many users are currently logged in. -* **No Immidiate Revokation** - There will be no process of immidiate session revokation on the serevr ad a session cookie will be valid till it expires, or they log out. +* **No Immediate Revocation** - There will be no process of Immediate session revocation on the server side-session cookie will be valid till it expires, or they log out. * **No Sign-Out Coordination** - Coordinating sign-outs from Open.IdentityServer with connected clients is less relable without server tracking of active sessions. -Open.IdentityServer Server-Side Sessions solves these issues by storing the contents of this cookie in a server side data store. This enables -in Open.IdentityServer the ability to: +Open.IdentityServer Server-Side Sessions solves these issues by storing the contents of this cookie in a server side data store. This gives Open.IdentityServer the ability to: -* Provide APIs for manging and querying active user sessions -* Support for explicit session revokation regardless of the cookie state in the browser +* Provide APIs for managing and querying active user sessions +* Support for explicit session revocation regardless of the cookie state in the browser * Storing session data server side, so browser cookie only contains an ID for the session nothing more Getting Started @@ -25,11 +22,7 @@ Getting Started 1. **Database schema** - Ensure your database is in the correct state. If you are coming from Duende - IdentityServer, there is nothing further to do - the schema is already compatible. - If you are migrating from IdentityServer4 and have not yet updated your schema to - match the Open.IdentityServer schema, you will need to do this first. See - :ref:`migration from IdentityServer4 ` for details. + Ensure your database is in the correct state. If you are coming from Duende IdentityServer, there is nothing further to do - the schema is already compatible. If you are migrating from IdentityServer4 and have not yet updated your schema to match the Open.IdentityServer schema, you will need to do this first. See :ref:`migration from IdentityServer4 ` for details. 2. **Enable server-side sessions** @@ -42,9 +35,7 @@ Getting Started 3. **Configure a session store** - ``AddServerSideSessions`` requires an implementation of ``IServerSideSessionStore`` - to persist session data. If you are using Entity Framework Core, this is provided - automatically when you configure the operational store: + ``AddServerSideSessions`` requires an implementation of ``IServerSideSessionStore`` to persist session data. If you are using Entity Framework Core, this is provided automatically when you configure the operational store: .. code-block:: csharp @@ -56,14 +47,11 @@ Getting Started b.UseSqlServer("ConnectionString"); }); - If you are not using the built-in EF Core store, you will need to provide your own - ``IServerSideSessionStore`` implementation. + If you are not using the built-in EF Core store, you will need to provide your own ``IServerSideSessionStore`` implementation. 5. **(Optional) Configure additional session options** - You can customize behavior via ``ServerSideSessionOptions``, such as how often - sessions are checked for expiration in the background, or coordinating this with - your sign-in cookie expiration: + You can customize behavior via ``ServerSideSessionOptions``, such as how often sessions are checked for expiration in the background, or coordinating this with your sign-in cookie expiration: .. code-block:: csharp From 47744535694c268eb84237b6df59fe0a3f0c8f61 Mon Sep 17 00:00:00 2001 From: James Britton Date: Mon, 28 Sep 2026 14:46:19 +0100 Subject: [PATCH 3/3] docs: added docs sestion for session management interface --- docs/topics/server_side_sessions.rst | 162 ++++++++++++++++++++++++++- 1 file changed, 158 insertions(+), 4 deletions(-) diff --git a/docs/topics/server_side_sessions.rst b/docs/topics/server_side_sessions.rst index c6838c833..bca7b8914 100644 --- a/docs/topics/server_side_sessions.rst +++ b/docs/topics/server_side_sessions.rst @@ -65,7 +65,161 @@ Getting Started options.ServerSideSessions.RemoveExpiredSessionsBatchSize = 100; }); -Managemet Interface -^^^^^^^^^^^^^^^^^^^ - -TODO: not yet implemented \ No newline at end of file +Management Interface +^^^^^^^^^^^^^^^^^^^^ + +Open.IdentityServer has a built-in session management interface, ``ISessionManagementService``, that allows you to query existing sessions and remove sessions. When you configure Open.IdentityServer to use server-side sessions, a default implementation is registered for this interface. + +The interface provides two methods: + +- ``Task> ISessionManagementService.QuerySessionsAsync(SessionQuery? filter, CancellationToken ct = default)`` + + Filters sessions using the ``SessionQuery`` object. The filter is optional; default values are used when it is not provided. + +- ``Task ISessionManagementService.RemoveSessionsAsync(RemoveSessionsContext context, CancellationToken ct = default)`` + + Removes sessions using the ``RemoveSessionsContext`` object. The context allows you to control which sessions are removed and what actions are taken as part of the removal. + +Data Types +^^^^^^^^^^ + +The following types are used by ``ISessionManagementService`` to query and manage sessions. + +SessionQuery +"""""""""""" + +``SessionQuery`` is used to filter results when calling ``QuerySessionsAsync``. + +.. list-table:: + :header-rows: 1 + :widths: 30 20 50 + + * - Property + - Type + - Description + * - ``ResultsToken`` + - ``string?`` + - Optional selector for current page location, contains identifier for the first element and last element in page of results. e.g. '0,24' + * - ``RequestPriorResults`` + - ``bool`` + - Specifies if instead of getting next page should get the previous page that ResultsToken identifies. Only valid if ResultsToken is specified. + * - ``CountRequested`` + - ``int`` + - Specifies the count requested per page, defaults to 25 + * - ``SubjectId`` + - ``string?`` + - Filters sessions with a specific subject id + * - ``SessionId`` + - ``string?`` + - Filters sessions with a specific session id + * - ``DisplayName`` + - ``string?`` + - Filters sessions with a specific display name + +QueryResult +"""""""""""""" + +``QueryResult`` wraps paged results returned from ``QuerySessionsAsync``. + +.. list-table:: + :header-rows: 1 + :widths: 30 20 50 + + * - Property + - Type + - Description + * - ``ResultsToken`` + - ``string?`` + - Token identifying the current page of results. Contains the first element and last element in page of results. e.g. '0,24' + * - ``HasPrevResults`` + - ``bool`` + - Specifies if there is a page of results before this page + * - ``HasNextResults`` + - ``bool`` + - Specifies if there is a page of results after this page + * - ``TotalCount`` + - ``int?`` + - Total sessions accross all pages of results + * - ``TotalPages`` + - ``int?`` + - Total number of pages for query result + * - ``CurrentPage`` + - ``int?`` + - Page numer of the current result collection + * - ``Results`` + - ``IReadOnlyCollection`` + - The collection of results for the current page + +UserSession +""""""""""" + +``UserSession`` represents a single server-side session record. + +.. list-table:: + :header-rows: 1 + :widths: 30 20 50 + + * - Property + - Type + - Description + * - ``SubjectId`` + - ``string`` + - The subject (user) identifier associated with the session. + * - ``SessionId`` + - ``string`` + - The unique identifier for the session + * - ``DisplayName`` + - ``string?`` + - An optional display name for the user + * - ``Created`` + - ``DateTime`` + - The date and time the session was created. + * - ``Renewed`` + - ``DateTime`` + - The date and time the session was last renewed + * - ``Expires`` + - ``DateTime?`` + - The date and time the session expires, if applicable + * - ``Issuer`` + - ``string?`` + - The issuer of the authentication ticket + * - ``Clients`` + - ``IEnumerable`` + - The clients associated with the session + * - ``AuthenticationTicket`` + - ``AuthenticationTicket?`` + - The user sessions suthentication ticket object + +RemoveSessionsContext +"""""""""""""""""""""" + +``RemoveSessionsContext`` controls which sessions are removed and what side effects occur when calling ``RemoveSessionsAsync``. + +.. list-table:: + :header-rows: 1 + :widths: 30 20 50 + + * - Property + - Type + - Description + * - ``SubjectId`` + - ``string?`` + - Optional if SessionId has value, limits removal to a specific subject id + * - ``SessionId`` + - ``string?`` + - Optional if SubjectId has value, limits removal to a specific session id + * - ``ClientIds`` + - ``IEnumerable?`` + - Optionally limits removal to sessions for specific clients + * - ``RemoveServerSideSession`` + - ``bool`` + - Whether to trigger session entity removal from the database + * - ``SendBackchannelLogoutNotification`` + - ``bool`` + - Whether to trigger backchannel logout notifications for removed sessions + * - ``RevokeTokens`` + - ``bool`` + - Whether to trigger session token removal + * - ``RevokeConsents`` + - ``bool`` + - Whether to trigger session consent removal \ No newline at end of file