How to implement user account / session switching at an IdP

This guide explains how an identity provider (IdP) can support account switching with the Connect2id server:

  • To enable users with multiple identities to have parallel IdP sessions in their brower (one session for each identity).

  • To enable a client application (OpenID relying party) to request the IdP to switch the user's identity, for example from a regular user to an administrator.

In the simple case, where the user is limited to one IdP session, a single session cookie is enough to represent that. For example:

sid: jHO2csdWyQH_I310OLmkxg.Cmw2Q_jmvmCBKetjnE3Sqw

To support parallel IdP sessions in a browser a special cookie schema is needed.

One approach is to store each session ID for a logged in user identity in a separate cookie, and use a pointer cookie to show the current active session:

sid-01: m8SSyLBjR1fzZjg9YIR1fw.4uArSMwwT3kLPoeg2NNGkA
sid-02: ZcussX5VUm0B3gW_I8MoTg.y_ipI6l9lFNlWdpit9m54w
sid-03: uej0Yfw6VE5KmU0o9fslog.kB4bs__7oAXB-ejjgGuQyQ
current-session: sid-02

How to request an account switch from a client application

An OpenID relying party can signal that a user wishes to switch to a different identity by making an OpenID authentication request with the optional prompt=select_account parameter:

https://c2id.com/login?
 response_type=code
 &scope=openid%20email
 &client_id=123
 &state=af0ifjsldkj
 &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
 &prompt=select_account

If you're using the OpenID Connect SDK for Java:

new AuthenticationRequest.Builder(
    ResponseType.CODE,
    new Scope("openid", "email"),
    new ClientID("123"),
    URI.create("https://client.example.org/cb"))
    .state(new State("af0ifjsldkj"))
    .prompt(new Prompt(Prompt.Type.SELECT_ACCOUNT))
    .build()
    .toURI();

The prompt parameter is specified in OpenID Connect Core 1.0.

How to handle an account switch request with the Connect2id server

When the Connect2id server receives an OpenID authentication request with prompt=select_account, it will return an auth prompt to the login page, with select_account set to true:

{
  "type"           : "auth",
  "sid"            : "g6f5K6Kf6EY11zC00errCf64yLtg9lLANAcnXQk2xUE",
  "display"        : "popup",
  "select_account" : true
}

When an account switch is signaled, the IdP should display a screen with the current browser sessions for the user, plus the option to log in as another not listed identity.

Example:

  • Continue as:
    • Alice (session in sid-01)
    • Bob (session in sid-02)
    • Claire (session in sid-03)
  • Log in as somebody else

To render the details of the avaiable user sessions (such as the session's username, user email, photo, etc), retrieve the session object for each sid-[n] cookie via the session store API of the Connect2id server:

GET /session-store/rest/v2/sessions HTTP/1.1
Host: c2id.com
Authorization: Bearer ztucZS1ZyFKgh0tUEruUtiSTXhnexmd6
SID: m8SSyLBjR1fzZjg9YIR1fw.4uArSMwwT3kLPoeg2NNGkA
HTTP/1.1 200 OK
Content-Type: application/json

{
  "sub"           : "alice",
  "auth_time"     : 1400491648,
  "creation_time" : 1400491648,
  "max_life"      : 20160,
  "auth_life"     : 10080,
  "max_idle"      : 1440,
  "claims"        : { "email"   : "[email protected]",
                      "name"    : "Alice Adams",
                      "picture" : "https://www.gravatar.com/avatar/205e460b479e2e5b48aec07710c08d50" }
}

If a sid-[n] has expired, you'll get a 404.

If the user chooses to go along with an existing session, let the login page restart the authZ session, but with the prompt=select_account parameter stripped from the OpenID request (so as not to trigger an auth prompt again).

If the user chooses to log with a non-listed account, authenticate the user, and then continue the original authZ session as usual.

When switching, make sure the current-session cookie value is updated accordingly.

User-initiated account switching

The IdP could also give users the option to switch their identity at login time, on their own initiative and without relying on a prompt=select_account from a client application. Simply include a UI control to access the account switching menu described above.

How to close a user session

If the users are given the option to close a session this can be implemented with a delete call to the session store web API of the Connect2id server.

How to start a user session outside a login flow

The IdP can login a user without any initiating request from a client application, by posting a new session to the Connect2id server.

Future improvements

We would like to simplify the implementation of account switching in a future release of the Connect2id server, so that the login page API can take care of much of what is explicitly required above. If you have comments or suggestions, or wish to discuss a use case, let us know.