Skip to content
Connect2id

Device SSO handler

1. Overview

Native applications with an active device session on the Connect2id server can sign in users and retrieve tokens through a single back-channel token request. This eliminates the need for the typical authentication and consent steps. This streamlined process is enabled by the native SSO extension for OpenID Connect, introduced in v16.0.

2. Device SSO handler SPI

A plugin interface (SPI) enables deployments to control the authorisation and token properties in response to a token request that relies on a present device session.

Features of the SPI:

  • Supports custom logic to determine the authorised scope and OpenID Connect claims, and whether to issue a refresh token and/or ID token. Also, to define token properties such as token lifetime.

  • Provides access to the device session, which includes information such as the client_ids of other native apps of the vendor the user has signed into on the device.

  • Requested scope values or claims that require a higher ACR level than the one the device session currently has can trigger an interaction_required error. This directs the client to make a new front-channel authorisation request.

Prior to calling the SPI the Connect2id server identifies / authenticates the client and validates the received ID token (subject_token), device secret (device_secret), and ensures their binding.

3. Available implementations

3.1 Default handler

The Connect2id server includes a default handler, which supports a range of configurations, such as which requested scope values require end-user interaction.

The handler source code is open (Apache 2.0 licensed).

Git repohttps://bitbucket.org/connect2id/grant-handlers

3.1.1 Configuration

The Connect2id server is shipped with a base configuration for the default device SSO handler located in WEB-INF/deviceSSOHandler.properties. It can be replaced or overridden with Java system properties.

Content of the shipped handler configuration file, with explanation of the properties:

# Enables / disables the handler. Disabled (false) by default.
op.deviceSSOHandler.enable=true

# Scope values that require end-user interaction (re-authentication or explicit
# consent) at the authorisation endpoint, as space separated list. Back-channel
# device SSO requests that include any of these scope values will trigger an
# "interaction_required" error at the token endpoint. None by default.
op.deviceSSOHandler.scopeRequiringInteraction=


### Access token ###

# The access token lifetime, in seconds. If zero, blank or omitted the default
# access token lifetime configured by "authzStore.accessToken.defaultLifetime"
# applies.
op.deviceSSOHandler.accessToken.lifetime=

# The access token encoding. The default value is SELF_CONTAINED.
#
# Supported encodings:
#
#     * IDENTIFIER -- The access token is a secure identifier. The associated
#       authorisation is looked up by a call to the Connect2id server token
#       introspection endpoint.
#     * SELF_CONTAINED -- Self-contained access token. The associated
#       authorisation is encoded in the access token itself, as a signed and
#       optionally encrypted JSON Web Token (JWT). Can also be looked up by a
#       call to the Connect2id server token introspection endpoint.
#
op.deviceSSOHandler.accessToken.encoding=SELF_CONTAINED

# If true enables additional encryption of self-contained (JWT-encoded) access
# tokens. Disabled (false) by default.
op.deviceSSOHandler.accessToken.encrypt=false

# Optional audience for the access tokens, as comma and / or space separated
# list of values.
op.deviceSSOHandler.accessToken.audienceList=

# Names of client metadata fields to include in the optional access token
# "data" field, empty set if none. To specify a member within a field that is a
# JSON object member use dot (.) notation.
op.deviceSSOHandler.accessToken.includeClientMetadataFields=


### Refresh token ###

# Enables / disables refresh token issue. Enabled (true) by default.
op.deviceSSOHandler.refreshToken.issue=true

# The refresh token lifetime, in seconds. Zero for no expiration. If -1, blank
# or omitted the default refresh token lifetime configured by
# "authzStore.refreshToken.defaultLifetime" applies.
op.deviceSSOHandler.refreshToken.lifetime=

# The refresh token maximum idle time, in seconds. Zero for no idle time
# expiration. The default value is 0.
op.deviceSSOHandler.refreshToken.maxIdleTime=0

# If true causes the refresh token to be updated (rotated) on each refresh
# token use. If blank or omitted the default rotation setting configured by
# "op.deviceSSOHandler.refreshToken.rotate" applies.
op.deviceSSOHandler.refreshToken.rotate=

# The transport to use for authorised claims. The default value is USERINFO:
#
# Supported values:
#
#     * USERINFO -- To release the claims at the UserInfo endpoint of the
#       Connect2id server by presenting the issued access token.
#     * ID_TOKEN -- To release the claims in the ID token. If an ID token is
#       not issued for a particular request the claims will be diverted for
#       release at the UserInfo endpoint.
#
op.deviceSSOHandler.claimsTransport=USERINFO

Example minimal configuration:

op.deviceSSOHandler.enable=true

4. How to develop your own device SSO handler

First, read our general guide for developing, annotating and packaging an SPI-based plugin.

The plugin must implement the DeviceSSOHandler SPI defined in the Connect2id server SDK:

Git repohttps://bitbucket.org/connect2id/server-sdk

The handler conveys an error by throwing a GeneralException. The exception message is logged internally and not conveyed to the client. The ErrorObject determines the HTTP status code, the error code and any other additional or custom parameters for the token error response.

If the Connect2id server detects an SPI implementation at startup it will log its loading under OP7106:

INFO MAIN [main] [OP7106] Loaded device SSO handler: class=com.nimbusds.openid.connect.provider.spi.impl.nativesso.handlers.LocalDeviceSSOHandler enabled=true

Note, the Connect2id server can load multiple device SSO handlers at startup, but only one may be enabled.