Web session bootstrap for native apps
This guide describes how a native app that has obtained an ID token for a user can seamlessly bootstrap a web session with the Connect2id server.
Use cases:
-
To seamlessly sign-in the native app user into one or more web apps.
-
To create or refresh a Connect2id server web session for the native app user.
Assumes Connect2id server 15.0 or later.
1. Flow variants
This guide describes three different flows to bootstrap a web session at the Connect2id server in order to enable seamless sign-in to a web app.
1.1 Direct web session bootstrap with the Connect2id server
This is the recommended flow. It requires no changes to the web app clients and to the handling of the OpenID authentication requests by the Connect2id server. It also aligns with the future direction to switch from ID tokens to device secrets (from native SSO) for enhanced security.
-
The native app exchanges the ID token for a web session bootstrap token.
-
The native app posts the token to a web session endpoint on the identity provider domain. The web session endpoint validates the token, creates a new Connect2id server web session, and redirects the browser to a target URL of the web app.
-
The web app makes an OpenID authentication request to sign-in the user. In the presence of an established web session with the Connect2id server the login prompt is skipped, resulting in a seamless sign-in experience.
1.2 Bootstrap via an OpenID authentication request
-
The native app exchanges the ID token for a web session bootstrap token.
-
The native app makes an OpenID authentication request to sign-in the user, passing the web session bootstrap token in an optional
login_hint_token
parameter. The Connect2id server validates the token and creates a new server web session for it, resulting in a seamless sign-in experience. -
Subsequent OpenID authentication requests from web apps that utilise the established Connect2id server web session will also result in a seamless sign-in experience.
1.3 Bootstrap via an OpenID authentication request initiated by the web app
-
The native app exchanges the ID token for a web session bootstrap token.
-
The native app opens a link to the target web app, passing the token in a agreed upon parameter, for example
login_hint_token
. -
The web app makes an OpenID authentication request to sign-in the user, passing the web session bootstrap token in an optional
login_hint_token
parameter. The Connect2id server validates the token and creates a new server web session for it, resulting in a seamless sign-in experience.
2. Native client
To allow a native client to obtain web session bootstrap tokens it must be registered with these capabilities:
-
The
grant_types
for the client must includeurn:ietf:params:oauth:grant-type:token-exchange
. -
The
scope
for the client must includeweb_session_bootstrap
.
Example registration request for a native client:
POST /clients HTTP/1.1
Content-Type: application/json
{
"application_type" : "native",
"grant_types" : [ "authorization_code",
"refresh_token",
"urn:ietf:params:oauth:grant-type:token-exchange" ],
"redirect_uris" : [ "com.example.app:///auth" ],
"token_endpoint_auth_method" : "none",
"code_challenge_method" : "S256",
"scope" : "openid email profile web_session_bootstrap"
}
The client registration guide has further examples.
3. ID token for web bootstrap token exchange
The native app obtains a web session bootstrap token by submitting an ID token for the signed-in user. It does it at the token endpoint of the Connect2id server, using a profile of the token exchange OAuth 2.0 grant (RFC 8693).
Token request:
- grant_type – Must be
urn:ietf:params:oauth:grant-type:token-exchange
. - scope – Must be
web_session_bootstrap
. - subject_token – Must be an ID token for the signed-in native app user.
Its
exp
(expiration) may be in the past. - subject_token_type – Must be
urn:ietf:params:oauth:token-type:id_token
.
Example:
POST /token HTTP/1.1
Host: demo.c2id.com
Content-Type: application/x-www-form-urlencoded
grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Atoken-exchange
&scope=web_session_bootstrap
&subject_token=eyJraWQiOiJDWHVwIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiJjbGFpcmUiLC...
&subject_token_type=urn%3Aietf%3Aparams%3Aoauth%3Atoken-type%3Aid_token
&client_id=123
Token response:
- access_token – The web session bootstrap token.
- token_type – Set to
Bearer
. - issued_token_type – Set to
urn:ietf:params:oauth:token-type:access_token
. - expires_in – The token validity lifetime, in seconds.
- scope – Set to
web_session_bootstrap
.
Example:
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"access_token" : "Ywjgiiy_8ERaV9D5DxhaBg.vWpARr3IzLLT_weUlltCPA",
"token_type" : "Bearer",
"issued_token_type" : "urn:ietf:params:oauth:token-type:access_token",
"expires_in" : 120,
"scope" : "web_session_bootstrap"
}
Token exchange handling
The exchange is to be handled by a Connect2id server plugin for the token exchange OAuth 2.0 grant.
Token request validation:
- The ID token signature must be validated, using the public Connect2id server JWK set.
- The ID token
iss
(issuer) must be the configured Connect2id server issuer URL. - The ID token
aud
(audience) must include theclient_id
value of the client that made the token request. - The ID token
exp
(expiration) may be in the past, as this claim is used to indicate the time after which the token must not be accepted by the OpenID relying party for the user authentication. Theexp
claim is not related to the user session expiration at the Connect2id server. The handler should, however, require a reasonable freshness of the ID token (see next point). - The ID token
iat
(issued-at time) should be reasonably recent and not older than the expiration time of refresh tokens issued to the native client. - The requested scope must be
web_session_bootstrap
and it must be present in the registered client metadata.
Web session bootstrap token:
- Must be issued as an
identifier-based (not
JWT-encoded) access token, to enforce one-time use of the token at the
introspection endpoint
with the
revoke=true
option. - The token subject must be the user identifier obtained from the ID token
sub
(subject). If the native app is registered for pairwise subjects, the ID tokensub
must be reversed (decrypted) to provide a correct web session bootstrap tokensub
. - The token audience must be the Connect2id server issuer
URL. If the token is going to be consumed in an
OpenID authentication request,
the
client_id
of the web app that is going to make the request should be added to the audience. - The token scope must be
web_session_bootstrap
. - The token lifetime should be sufficient to allow its use according to the intended flow.
- The token
data
object may be populated with the ID tokenauth_time
,acr
and other claims to configure the web session later.
Connect2id server deployments that choose to utilise the web-based handler (web-hook) to process requests for web session bootstrap tokens should set up the handler according to the above requirements.
Example configuration, to accept ID tokens and verify their digital signature prior to invoking the web-hook:
op.grantHandler.tokenExchange.webAPI.enable=true
op.grantHandler.tokenExchange.webAPI.url=[web-hook-url]
op.grantHandler.tokenExchange.webAPI.apiAccessToken=[web-hook-access-token]
op.grantHandler.tokenExchange.webAPI.subjectToken.types=urn:ietf:params:oauth:token-type:id_token
op.grantHandler.tokenExchange.webAPI.subjectToken.jwtVerification.1.jwkSetURI=[connect2id-server-jwk-set-url]
op.grantHandler.tokenExchange.webAPI.subjectToken.jwtVerification.mustPass=true
The handler must validate the ID token according to the token request validation steps 2 through 6 above.
To allow the issue of the web session bootstrap token the handler returns a response with the following parameters:
- sub – The user identifier from the ID token.
- issued_token_type – Must be
urn:ietf:params:oauth:token-type:access_token
. - scope – Must be
["web_session_bootstrap"]
. - access_token.lifetime – The web session bootstrap token validity, in seconds.
- access_token.encoding – Must be
IDENTIFIER
. - access_token.audience – Must contain the Connect2id server issuer URL.
- refresh_token.issue – Must be
false
.
To deny the issue the handler returns an error.
Example handler response:
{
"sub" : "164476e0-5c10-4cf0-bf75-b30fec2ba925",
"issued_token_type" : "urn:ietf:params:oauth:token-type:access_token",
"scope" : [ "web_session_bootstrap" ],
"access_token" : { "lifetime" : 120,
"encoding" : "IDENTIFIER",
"audience" : [ "https://demo.c2id.com" ] },
"refresh_token" : { "issue" : false }
}
4. Web session bootstrap endpoint
The endpoint to create web sessions with bootstrap tokens must fulfil the following:
-
Must be hosted on the same web domain as the authorisation endpoint (login page) of the Connect2id server.
-
Must support token submission via HTTP GET and POST, per OAuth 2.0 Bearer Token Usage (RFC 6750).
-
Must support a parameter, e.g.
redirect_uri
, where the browser is to be redirected if the web session bootstrap is successfully validated. -
Must validate the token, with replay prevention. This is done at the Connect2id server token introspection endpoint using the
revoke=true
option. If the token is invalid or expired, the endpoint must return a 401 Unauthorized error. -
If the token is valid, must first check whether a session cookie for a valid web session is not already present. If a web session is already present, the endpoint should not create a new web session, and proceed to redirect to the requested URL. If the
sub
(subject) of the present web session and the token are not identical, this must be logged as an error, and redirection must not take place. -
Create a new web session for the token
sub
(subject). If ID tokenauth_time
,acr
and other claims were passed via the tokendata
they can be used to configure the new web session. Alternatively, the session may be given a specialacr
to clearly indicate that it was bootstrapped with a token. -
Use the
SID
(session ID) to set a new session cookie and redirect to the requested URL.
Example request to the web session bootstrap endpoint:
https://demo.c2id.com/web-session-bootstrap?
access_token=Ywjgiiy_8ERaV9D5DxhaBg.vWpARr3IzLLT_weUlltCPA
&redirect_uri=https%3A%2F%2Fweb-app.example.com%2Faccount%2FLB6P
Example success response with a redirection:
HTTP/1.1 302 Found
Location: https://web-app.example.com/account/LB6P
Set-Cookie: sid=WYqFXK7Q4HFnJv0hiT3Fgw.-oVkvSXgalUuMQDfEsh1lw; Domain=demo.c2id.com; Path=/; Secure; HttpOnly
5. OpenID authentication with a web session bootstrap token
A client in possession of a web session bootstrap token is able to make an OpenID authentication request where the login prompt for the user is bypassed.
Connect2id server configuration:
- op.authz.requestParamsInAuthPrompt
must be set to include the
client_id
andlogin_hint_token
values.
Example:
op.authz.requestParamsInAuthPrompt=client_id,login_hint_token
To accept bootstrap tokens the authorisation session handler must act as follows:
-
On receiving an authentication prompt the handler must check if a token was passed in the
request.login_hint_token
parameter. -
The token must be validated, with replay prevention. This is done at the Connect2id server token introspection endpoint using the
revoke=true
option. Theclient_id
of the OpenID authentication request (obtained fromrequest.client_id
) should be checked to be present in the tokenaud
(audience). If the token is invalid or expired, the handler must present the regular login prompt to the user. -
Submit the token
sub
(subject) in response to the authentication prompt. If ID tokenauth_time
,acr
and other claims were passed via the tokendata
they can be used to configure the new web session. Alternatively, the session may be given a specialacr
to clearly indicate that it was bootstrapped with a token.
6. Future directions
6.1 Switch to native SSO device secrets, with optional sender constraining
Connect2id is researching an alternative flow where the native app is
provisioned with a device_secret
that links to a device
session managed by the identity
provider. Device sessions and secrets were originally devised for the OpenID
Connect native SSO.
Replacing the ID token with a device_secret
in the token
exchange is going to represent a significant security
enhancement:
- The
device_secret
and the web session bootstrap token can be sender-constrained, with DPoP or mTLS. The use of ID tokens in the token exchange offer no such possibility. This reduces the risk of unauthorised session creation in case of a token leak. - Closing, expiration or revocation of the device session immediately removes the ability of the native app to obtain web session bootstrap tokens. This can be further chained to automatically close any web sessions that were derived from it by means of bootstrap tokens.
- Straightforward conversion from a device to a web session.
6.2 Built-in support
Given sufficient interest from customers on the enterprise plan Connect2id will consider providing a built-in token exchange profile for the web session bootstrap tokens and the endpoint for their consumption.
7. Credits
The flows described here are based on the following previous work:
- OAuth 2.0 Bootstrap to Web Session (draft 02), by George Fletcher (2013-01-07).
- Work on Connect2id server deployments.