From d5f626476359e807c9457d2369d72acd8390574f Mon Sep 17 00:00:00 2001 From: Michael Schwartz Date: Wed, 28 Dec 2022 17:27:12 -0600 Subject: [PATCH 1/2] Docs: Auth Server Sessions Added content related to session management --- .../openid-features/logout/README.md | 12 ++- .../auth-server/session-management/README.md | 100 ++++++++---------- .../session-management/idp-v-rp.md | 22 ++-- .../multiple-browser-sessions.md | 13 +-- .../multiple-sessions-one-browser.md | 18 ++-- docs/admin/planning/caching.md | 6 +- docs/admin/planning/timeout-management.md | 3 +- docs/admin/planning/use-cases.md | 6 +- 8 files changed, 90 insertions(+), 90 deletions(-) diff --git a/docs/admin/auth-server/openid-features/logout/README.md b/docs/admin/auth-server/openid-features/logout/README.md index ff91f256c5f..2401b9646a7 100644 --- a/docs/admin/auth-server/openid-features/logout/README.md +++ b/docs/admin/auth-server/openid-features/logout/README.md @@ -9,7 +9,13 @@ tags: # Overview -Please use the left navigation menu to browse the content of this section while we are still working on developing content for `Overview` page. +Although Jans Auth Server has a `session_id` for each person who has authenticated, +applications generally have their *own* sessions. Upon logout from an OpenID Provider, ideally all RPs are notified, so they can also their local sessions. The OpenID solution to implement logout is currently described in the [OpenID Connect Front Channel Logout specification](http://openid.net/specs/openid-connect-frontchannel-1_0.html). -!!! Contribute -If you’d like to contribute to this document, get started with the [Contribution Guide](https://docs.jans.io/head/CONTRIBUTING/#contributing-to-the-documentation) \ No newline at end of file +In practice, here's how it works: + + - Jans Auth Server `end_session` endpoint returns an HTML page, which contains an iFrame for each application to which the user has authenticated. + - The iFrame contains a link to each application's respective logout URL. + - The special HTML page should be loaded in the background and not displayed to the user. + - The iFrame URLs should be loaded by the browser. + - Now, upon logout, the user is calling the logout page of each application, the local cookies are cleared, and the user is signed out of all applications. diff --git a/docs/admin/auth-server/session-management/README.md b/docs/admin/auth-server/session-management/README.md index 7d823f05be5..cdeac0c893f 100644 --- a/docs/admin/auth-server/session-management/README.md +++ b/docs/admin/auth-server/session-management/README.md @@ -7,41 +7,46 @@ tags: # Overview -A session is a reference identifier on the Jans Auth Server that connect to a -person's authentication state. Most commonly, the session is stored in -the person's web browser, in the `session_id` cookie. OpenID Native SSO also -defines a way for mobile apps from the same vendor to use the iOS or Android -protected secret storage to store a session. By correlating the session, the IDP -can return an identity assertion (id_token) to a client without needing to -authenticate the person. Thus sessions enable SSO. +A session is a reference identifier on the Jans Auth Server that connects to a +person's authentication state. During an authentication workflow, Auth Server writes a cookie with the `session_id` in the person's browser. OpenID Native +SSO defines a way for mobile apps from the same vendor to use the iOS or Android +protected secret storage to store the `session_id`. By correlating the session, +the IDP can return an identity assertion (id_token) to a client without needing +to re-authenticate the person. SSO ensues. For example, let's say a person uses a browser to navigate to the website of Relying Party (RP1), which redirects to Jans Auth Server for authentication. Once the person is authenticated, the OP creates a `session_id` cookie, sets the -state to `authenticated`, and places it in the cache. If the user hits RP2, -it will redirect the user to the OP for authentication, and since the session is -already authenticated, the OP authenticates the user automatically for RP2 -(without an authentication prompt). - -Jans Auth Server stores user session data in its cache, whether it's in-memory, -redis, memcached or the databse, depending on the `cacheProviderType` -configuration property. - -The OP session can have one of two states: - -- `unauthenticated` - when the end-user reaches the OP but has not yet authenticated, a session object is created and put in the cache with the `unauthenticated` state. -- `authenticated` - when the user has successfully authenticated at the OP. - - -- **sessionIdLifetime** - lifetime of the OP session in seconds. It sets both the - -- **session_id** cookie expiration property as well as the OP session object expiration (if -- **serverSessionIdLifetime** is not set or equals `0` which is default behavior) in the persistence. It's a global property for sessions. Starting in version `4.1`, it is possible to set value to 0 or -1, which means that expiration is not set (not available in `3.1.3` or earlier except `2.4.4`). In this case, the `session_id` cookie expiration value is set to the `session` value, which means it's valid until the browser session ends. -- **serverSessionIdLifetime** - dedicated property to control lifetime of the server side OP session object in seconds. Overrides `sessionIdLifetime`. By default value is 0, so object lifetime equals `sessionIdLifetime` (which sets both cookie and object expiration). It can be useful if goal is to keep different values for client cookie and server object. -- **sessionIdUnusedLifetime** - unused OP session lifetime in seconds (set by default to 1 day). If an OP session is not used for a given amount of time, the OP session is removed. -- **sessionIdUnauthenticatedUnusedLifetime** - lifetime in seconds of `unauthenticated` OP session. This determines how long the user can be on the login page while unauthenticated. -- **sessionIdRequestParameterEnabled** - Boolean value specifying whether to enable session_id HTTP request parameter. Default value is `false` (since 4.2). -- **sessionIdPersistOnPromptNone** - specifies whether to persist or update the session object with data if `prompt=none`. Default value is `true`, so session is persisted by default. +state to `authenticated`, and places it in the cache. If the person mavigates +their browser to the website of RP2, it redirects to the OP for authentication; since the `session_id` detected via the cookie is already authenticated, the OP +authenticates the person automatically for RP2 (without an authentication +prompt). + +Jans Auth Server stores user session data in its cache. Auth Server performance +retrieving the session will vary depending on whether the session is stored in memory, Redis, Memcached or the database, as controlled by the +`cacheProviderType` Auth Server configuration property. + +The Auth Server session can have one of two states: + +- `unauthenticated` - a browser that has started, but not completed an authentication workflow. +- `authenticated` - when a person has successfully authenticated + +The following Auth Server configuration properties are related to sessions: + +- **sessionIdLifetime** - lifetime of the OP session in seconds. It sets both the `session_id` cookie expiration property as well as the OP session object expiration (if `serverSessionIdLifetime` is not set or equals 0 which is default behavior) in the persistence. Upi cam set the value to 0 or -1, which means that expiration is not set. In this case, the sesion is valid until the browser +session ends. Default value is `86400`. +- **serverSessionIdLifetime** - dedicated property to control lifetime of the server side OP session object in seconds. Overrides `sessionIdLifetime`. By default value is `0`, so object lifetime equals `sessionIdLifetime` (which sets both cookie and object expiration). It can be useful if goal is to keep +different values for client cookie and server object. Default value is `86400`. +- **sessionIdUnusedLifetime** - unused OP session lifetime in seconds. If an OP session is not used for a given amount of time, the OP session is removed. +Default value is `86400`. +- **sessionIdUnauthenticatedUnusedLifetime** - lifetime in seconds of `unauthenticated` OP session. This determines how long the user can be on the login page while unauthenticated. Default value is `120`. +- **sessionIdRequestParameterEnabled** - Boolean value specifying whether to enable `session_id` HTTP request parameter. Default value is `False`. +- **sessionIdPersistOnPromptNone** - specifies whether to persist or update the session object with data if `prompt=none`. Default value is `True`. - **invalidateSessionCookiesAfterAuthorizationFlow** - this is special property which specifies whether to invalidate `session_id` and `consent_session_id` cookies right after successful or unsuccessful authorization. +- **changeSessionIdOnAuthentication** - Using a different session after the user authenticates improves security. The default value is `True`. +- **sessionIdPersistInCache** - If True, sessions are stored according to `cacheProviderType`. Otherwise, sessions are persisted in the database. + Default value is `False`. +- **sessionIdPersistInCache** Default value is `False`. For both `unused` properties, Jans Auth Server calculates this period as `currentUnusedPeriod = now - session.lastUsedAt`. So for OP session with states: @@ -50,36 +55,20 @@ For both `unused` properties, Jans Auth Server calculates this period as `curren Jans Auth Server updates `lastUsedAt` property of the session object: -- initially, it is set during creation -- it is updated during each authentication attempt (whether successful or not successful) - -It is important to note that the OP session `lastUsedAt` property is not updated -during RP usage. - -## Logout - -An application may also store its *own* session for the user. Upon logout from the OP, all RPs need to be notified so local sessions can also be cleared/ended. The best way to handle this currently is through "front-channel logout", as described in the [OpenID Connect Front Channel Logout specification](http://openid.net/specs/openid-connect-frontchannel-1_0.html). - -In practice, here's how it works: - - - Jans Auth Server `end_session` endpoint returns an HTML page, which contains an iFrame for each application to which the user has authenticated. - - The iFrame contains a link to each application's respective logout URL. - - The special HTML page should be loaded in the background and not displayed to the user. - - The iFrame URLs should be loaded by the browser. - - Now, upon logout, the user is calling the logout page of each application, the local cookies are cleared, and the user is signed out of all applications. +- During creation +- For each Auth Server authentication attempt (regardless of success) -Learn more about the flow for logout across many applications in the -[logout docs](../openid-features/logout/README.md). +## Killing Sessions -## Session Revocation +The [End Session endpoint](../endpoints/end-session.md) (`/end_session`) +is where the user can end their own session. See [OpenID Logout](../logout/README.md) for more information. -Note, the [End Session endpoint](../endpoints/end-session.md) (`/end_session`) is where the user can end their own session. To end another person's session, you need to use the [Session -Revocation Endpoint](../endpoints/session-revocation.md) (`/revoke_session`). +To end another person's session, Jans Auth Server has a [Session Revocation Endpoint](../endpoints/session-revocation.md) (`/revoke_session`). ## Session Event Interception Script It is possible to add custom business logic as Jans Auth Server detects -different session events. See: +session events, see: * [Application Session](../../../developer/scripts/application-session.md) * [End Session](../../../developer/scripts/end-session.md) @@ -88,8 +77,9 @@ different session events. See: ### How can we force the user to log out if the user is idle on the RP for 4 hours? -The OP doesn't know anything about end-user activity on the RP. Therefore, the RP has to track activity internally, and when the inactivity period is reached (in this case, 4 hours) the RP has to perform front-channel logout. +The OP doesn't know anything about end-user activity on the RP. Therefore, the RP has to track activity internally, and when the inactivity period is reached (in this case, 4 hours) the RP should perform front-channel logout. ### How can we force the user to log out if the browser is closed? -Setting `sessionIdLifetime` to `-1` value sets the `session_id` cookie value to `expires=session`, and sets the OP session object to not have an expiration time. Most browsers clear cookies with `expires=session` when the browser is closed, removing the session object at that time. +Setting `sessionIdLifetime` to `-1` value sets the `session_id` cookie value to `expires=session`, and sets the OP session object to not have an expiration time. Most browsers clear cookies with `expires=session` when the browser is closed, removing the session object at that time. Javascript may be necessary to override +undesirable default browser behavior. diff --git a/docs/admin/auth-server/session-management/idp-v-rp.md b/docs/admin/auth-server/session-management/idp-v-rp.md index f156df4c649..e704e0dfd3f 100644 --- a/docs/admin/auth-server/session-management/idp-v-rp.md +++ b/docs/admin/auth-server/session-management/idp-v-rp.md @@ -5,14 +5,18 @@ tags: - session --- -## This content is in progress +## IDP versus RP session -The Janssen Project documentation is currently in development. Topic pages are being created in order of broadest relevance, and this page is coming in the near future. +Applications generally have their own session cookie (the "RP Session"). +This makes sense, because the RP only redirects to the IDP for authentication +if it cannot find its own local cookie. If a user has a session with many +RP's, achieving simultaneous logout across all sites is a challenge--something +which your business leaders may not appreciate. While OpenID proposes several +solutions to logout, none are idea. Fundamentally, logout is an asynchronous +challenge. A given RP may be disconnected from the network. Thus logout +messages sent to RP's that are not received must be replayed. The +[IETF Sec Events Workgroup](https://datatracker.ietf.org/doc/charter-ietf-secevent/01/) has been working on standards to handle logout (and other asynchronous +requirements). But adoption of this architecture is not common. -## Have questions in the meantime? - -While this documentation is in progress, you can ask questions through [GitHub Discussions](https://github.com/JanssenProject/jans/discussion) or the [community chat on Gitter](https://gitter.im/JanssenProject/Lobby). Any questions you have will help determine what information our documentation should cover. - -## Want to contribute? - -If you have content you'd like to contribute to this page in the meantime, you can get started with our [Contribution guide](https://docs.jans.io/head/CONTRIBUTING/). \ No newline at end of file +Another challenge of RP sessions is that they may have a different timeout +for inactivity. See [Planning Guide Timeout Management](../../planning/timeout-management.md) for more details. diff --git a/docs/admin/auth-server/session-management/multiple-browser-sessions.md b/docs/admin/auth-server/session-management/multiple-browser-sessions.md index f156df4c649..397dca647f4 100644 --- a/docs/admin/auth-server/session-management/multiple-browser-sessions.md +++ b/docs/admin/auth-server/session-management/multiple-browser-sessions.md @@ -5,14 +5,7 @@ tags: - session --- -## This content is in progress +## Multiple Browser Authentication -The Janssen Project documentation is currently in development. Topic pages are being created in order of broadest relevance, and this page is coming in the near future. - -## Have questions in the meantime? - -While this documentation is in progress, you can ask questions through [GitHub Discussions](https://github.com/JanssenProject/jans/discussion) or the [community chat on Gitter](https://gitter.im/JanssenProject/Lobby). Any questions you have will help determine what information our documentation should cover. - -## Want to contribute? - -If you have content you'd like to contribute to this page in the meantime, you can get started with our [Contribution guide](https://docs.jans.io/head/CONTRIBUTING/). \ No newline at end of file +Unfortunately, each browser has its own session cookies, and therefore +its own sessions. diff --git a/docs/admin/auth-server/session-management/multiple-sessions-one-browser.md b/docs/admin/auth-server/session-management/multiple-sessions-one-browser.md index 056a9d371a3..377fcb1abf6 100644 --- a/docs/admin/auth-server/session-management/multiple-sessions-one-browser.md +++ b/docs/admin/auth-server/session-management/multiple-sessions-one-browser.md @@ -3,24 +3,28 @@ tags: - administration - auth-server - session + - Account Chooser --- ## Select Account -AS supports different accounts. To be able select account or login as another user within same user-agent authorization request must have `prompt=select_account`. +A person may have several accounts in a single Jans Auth Server instance. For +example, you may have several diffent Gmail ids. An RP can enable a person +to choose their account by sending an [OpenID Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest) with the +parameter `prompt=select_account`. + +For example, following an initial authentication, the session cookie on a person's browser would contain the following data: -When user is logged in cookies looks as: ``` session_id: de510ab6-b06c-4393-86d8-12a7c501aafe current_sessions: ["de510ab6-b06c-4393-86d8-12a7c501aafe"] ``` -If RP sends Authorization Request with `prompt=select_account` and selects hits `Login as another user` button and authenticate then cookies looks as: +Continuing this example, if an RP sent an additional Authentication Request with `prompt=select_account`, Auth Server may return a page enabling the person +to select their account, or even to login as a different account. Once authenticated as a different user, the `current_sessions` cookie would reference +all the current sessions, like this: + ``` session_id: c691e83d-eb1b-41f0-b453-fab905681b5b current_sessions: ["de510ab6-b06c-4393-86d8-12a7c501aafe", "c691e83d-eb1b-41f0-b453-fab905681b5b"] ``` - -AS represents accounts based on `current_sessions` cookies. It may contain outdated references but AS will filter it out and update on request. Thus page represents always actual/active sessions. - -![selectAccount](../img/admin-guide/selectAccount.png) diff --git a/docs/admin/planning/caching.md b/docs/admin/planning/caching.md index 392263aec97..7181044e890 100644 --- a/docs/admin/planning/caching.md +++ b/docs/admin/planning/caching.md @@ -9,7 +9,9 @@ tags: There are two reasons to use caching. First, to improve performance by reducing the number of writes to the disk. Second, to share session data in a clustered deployment. Janssen supports a few different options for -caching. +caching, as controlled by the `cacheProviderType`. Also keep in mind that unless +the `sessionIdPersistInCache` is set to `True`, Auth Server will store sessions +in the database. 1. **In-Memory** If you only have one server, you can use RAM as the cache. Watch the memory usage of Auth Server--if it gets too high you may want to @@ -25,7 +27,7 @@ for caching. 1. **Redis** The best choice if you need a cache service for LDAP, RDBMS, or Spanner. Great performance and low cache miss rate. Commercial Redis -supports TLS, which is a good option if you need secure communication. +supports TLS, which is a good option if you need secure communication. 1. **Memcached** Still a good choice, especially if that's what you already run for other applications. We have observed a slightly higher cache miss diff --git a/docs/admin/planning/timeout-management.md b/docs/admin/planning/timeout-management.md index 6c78d61cdcd..2a13971f8a5 100644 --- a/docs/admin/planning/timeout-management.md +++ b/docs/admin/planning/timeout-management.md @@ -12,7 +12,8 @@ is rarely attainable. Normally the application needs to handle gracefully the case when the IDP session expires first. And if the application session expires first, it may need to trigger a logout event at the OpenID Provider. -Below is a list of some of the timeouts to consider: +Below is a list of some of the Auth Server configuration properties for timeouts +that you should consider: 1. **sessionIdLifetime**: diff --git a/docs/admin/planning/use-cases.md b/docs/admin/planning/use-cases.md index e9f37a1447f..a06e0c32e06 100644 --- a/docs/admin/planning/use-cases.md +++ b/docs/admin/planning/use-cases.md @@ -9,8 +9,8 @@ tags: Web browser SSO is one of the main use cases for Janssen. The OpenID Connect interfaces of the Auth Server provide the identity layer that manages -authentication and B-SSO. Auth Server tracks web browser sessions via a cookie. An -end user may actually have several active sessions, although only one session is +authentication and B-SSO. Auth Server tracks web browser sessions via a cookie. +An end user may actually have several active sessions, although only one session is active. For example, below is a hypothetical session cookie: ``` @@ -162,4 +162,4 @@ to something. Note: Authorizations are stored relative to a person's entity in the database. How a person views and revokes consent is outside the scope of Auth Server. To view a person's consents, you need to use the config API, as this information -is not shared via OpenID Connect or SCIM. \ No newline at end of file +is not shared via OpenID Connect or SCIM. From 3fa53ae37cb3a9f0ab8d4b9001e852919f3654a1 Mon Sep 17 00:00:00 2001 From: Michael Schwartz Date: Thu, 29 Dec 2022 10:11:33 -0600 Subject: [PATCH 2/2] Docs: Auth Server / Sessions Fixes and edits to the Auth Server / Sessions section --- .../auth-server/session-management/README.md | 2 +- .../session-management/idp-v-rp.md | 5 +-- .../multiple-sessions-one-browser.md | 34 +++++++++++------- .../auth-server/tokens/openid-id-token.md | 12 +------ .../auth_server_sessions_selectAccount.png | Bin 0 -> 12961 bytes 5 files changed, 26 insertions(+), 27 deletions(-) create mode 100644 docs/assets/auth_server_sessions_selectAccount.png diff --git a/docs/admin/auth-server/session-management/README.md b/docs/admin/auth-server/session-management/README.md index cdeac0c893f..bd3b4e06165 100644 --- a/docs/admin/auth-server/session-management/README.md +++ b/docs/admin/auth-server/session-management/README.md @@ -65,7 +65,7 @@ is where the user can end their own session. See [OpenID Logout](../logout/READM To end another person's session, Jans Auth Server has a [Session Revocation Endpoint](../endpoints/session-revocation.md) (`/revoke_session`). -## Session Event Interception Script +## Session Event Interception Scripts It is possible to add custom business logic as Jans Auth Server detects session events, see: diff --git a/docs/admin/auth-server/session-management/idp-v-rp.md b/docs/admin/auth-server/session-management/idp-v-rp.md index e704e0dfd3f..bd0f4418b3f 100644 --- a/docs/admin/auth-server/session-management/idp-v-rp.md +++ b/docs/admin/auth-server/session-management/idp-v-rp.md @@ -12,11 +12,12 @@ This makes sense, because the RP only redirects to the IDP for authentication if it cannot find its own local cookie. If a user has a session with many RP's, achieving simultaneous logout across all sites is a challenge--something which your business leaders may not appreciate. While OpenID proposes several -solutions to logout, none are idea. Fundamentally, logout is an asynchronous +solutions to logout, none are ideal. Fundamentally, logout is an asynchronous challenge. A given RP may be disconnected from the network. Thus logout messages sent to RP's that are not received must be replayed. The [IETF Sec Events Workgroup](https://datatracker.ietf.org/doc/charter-ietf-secevent/01/) has been working on standards to handle logout (and other asynchronous requirements). But adoption of this architecture is not common. Another challenge of RP sessions is that they may have a different timeout -for inactivity. See [Planning Guide Timeout Management](../../planning/timeout-management.md) for more details. +for inactivity. See the Janssen Planning Guide page on +[Timeout Management](../../planning/timeout-management.md) for more details. diff --git a/docs/admin/auth-server/session-management/multiple-sessions-one-browser.md b/docs/admin/auth-server/session-management/multiple-sessions-one-browser.md index 377fcb1abf6..09074e06961 100644 --- a/docs/admin/auth-server/session-management/multiple-sessions-one-browser.md +++ b/docs/admin/auth-server/session-management/multiple-sessions-one-browser.md @@ -8,23 +8,31 @@ tags: ## Select Account -A person may have several accounts in a single Jans Auth Server instance. For -example, you may have several diffent Gmail ids. An RP can enable a person -to choose their account by sending an [OpenID Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest) with the -parameter `prompt=select_account`. +A person may have several accounts on a single Jans Auth Server instance. For +example, it is common to have several Gmail accounts. Jans Auth Server uses two +cookies to track which accounts are associated with a browser: `session_id` and +`current_sessions`. -For example, following an initial authentication, the session cookie on a person's browser would contain the following data: +Below is an example or a person with two authenticated sessions: ``` session_id: de510ab6-b06c-4393-86d8-12a7c501aafe -current_sessions: ["de510ab6-b06c-4393-86d8-12a7c501aafe"] +current_sessions: ["de510ab6-b06c-4393-86d8-12a7c501aafe", "c691e83d-eb1b-41f0-b453-fab905681b5b"] ``` -Continuing this example, if an RP sent an additional Authentication Request with `prompt=select_account`, Auth Server may return a page enabling the person -to select their account, or even to login as a different account. Once authenticated as a different user, the `current_sessions` cookie would reference -all the current sessions, like this: +An RP trigger Auth Server's built in Account Chooser feature by sending an +[OpenID Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest) with the parameter `prompt=select_account`. In +this case, Auth Server renders the default page: +`/opt/jans/jetty/jans-auth/custom/pages/selectAccount.xhtml` -``` -session_id: c691e83d-eb1b-41f0-b453-fab905681b5b -current_sessions: ["de510ab6-b06c-4393-86d8-12a7c501aafe", "c691e83d-eb1b-41f0-b453-fab905681b5b"] -``` +This page iterates `current_sessions` and enables the person +to login as a different account, for example: + +![Sample Select Account login page screenshot](../../assets/auth_server_sessions_selectAccount.png) + +You can override this page if you place a `selectAccount.xhtml` in +`custom/pages`. + +Other ways to handle account selection are possible using the Person +Authentication interception script, if you detect the `prompt=login` +parameter. diff --git a/docs/admin/auth-server/tokens/openid-id-token.md b/docs/admin/auth-server/tokens/openid-id-token.md index fe86ea4d9cf..1182d607c84 100644 --- a/docs/admin/auth-server/tokens/openid-id-token.md +++ b/docs/admin/auth-server/tokens/openid-id-token.md @@ -5,14 +5,4 @@ tags: - token --- -## This content is in progress - -The Janssen Project documentation is currently in development. Topic pages are being created in order of broadest relevance, and this page is coming in the near future. - -## Have questions in the meantime? - -While this documentation is in progress, you can ask questions through [GitHub Discussions](https://github.com/JanssenProject/jans/discussion) or the [community chat on Gitter](https://gitter.im/JanssenProject/Lobby). Any questions you have will help determine what information our documentation should cover. - -## Want to contribute? - -If you have content you'd like to contribute to this page in the meantime, you can get started with our [Contribution guide](https://docs.jans.io/head/CONTRIBUTING/). \ No newline at end of file +## OpenID Connect `id_token` diff --git a/docs/assets/auth_server_sessions_selectAccount.png b/docs/assets/auth_server_sessions_selectAccount.png new file mode 100644 index 0000000000000000000000000000000000000000..f895dadc36a7f1a9d9327075e85b333324be5e13 GIT binary patch literal 12961 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 mLQAY!(C literal 0 HcmV?d00001