Connect2id server 7.10


Release 7.10 of the OpenID Connect / OAuth 2.0 server adds a new SPI for plugging custom checks when registering or updating clients. Shaping (modification) of the registered client metadata is also supported.

The SPI can be particularly useful when the Connect2id server is configured for open client registration and there is no developer portal in front of the client registration endpoint to enforce specific checks and policies.

For more details check out the release notes below.


To download a ZIP package of Connect2id server 7.10:

SHA-256: a388b3827a53dbf2f53767a31086c66bf200eb7985192eab1eda45f9e85f714d

As WAR package only:

SHA-256: 51146f1294e5d962dc0262aaef010badb5d5acd0df2970e128ee886f3aa8e39f


Contact Connect2id support.

Release notes

7.10 (2019-04-15)


  • /WEB-INF/

    • See FinalMetadataValidator SPI description below.


  • com.nimbusds.openid.connect.provider.spi.reg.FinalMetadataValidator

    • New Service Provider Interface (SPI) for performing additional validation and / or shaping of OAuth 2.0 client / OpenID relying party metadata, after the Connect2id server has completed its own standard validations. The loaded and enabled SPI implementations will be called (in no particular order) when a new client is registered (via HTTP POST request) or updated (via HTTP PUT request).

      A simple internal implementation is included to check if the hostname of the logo_uri and policy_uri parameters (if set) matches a host in the redirect_uris (if set), according to OpenID Connect Dynamic Client Registration 1.0 incorporating errata set 1, section 9.1. see These checks can be enabled / disabled from the /WEB-INF/ configuration file. Java system property override is supported.

Resolved issues

  • Return a redirecting login_required error instead of a non-redirecting error in the authorisation session web API when the OpenID authentication request includes an id_token_hint and its subject doesn't match the one which got logged in (issue server/430).

  • Moves ID token generation for OpenID authentication requests with response_type=code from the authorisation session endpoint to the token endpoint. This ensures ID token issue events are not falsely generated when the relying party fails to complete the token request. This bug affects plugins that use the IDTokenIssueEventListener SPI (issue server/434). The retrieval of OpenID claims to be fed into the ID token is also moved to the token endpoint.

  • Clearing a tenant's data now also covers the cached JWT claims of request objects (JAR). Applies to the multi-tenant edition only (issue server/427).

  • Updates log messages OP5167, OP5166, OP5184 and OP5169 to include additional information on the number of revoked authorisations when a client is deleted (issue server/435).

  • Removes incompatible shared="true" attribute for all SQL store connectors in WEB-INF/infinispan-local-h2.xml (issue server/426).

Dependency changes

  • Upgrades to com.nimbusds:c2id-server-sdk:4.2

  • Updates to com.nimbusds:oauth2-oidc-sdk:6.8

  • Upgrades to com.nimbusds:oauth2-authz-store:11.3

  • Updates to com.nimbusds:common:2.33

Connect2id server 7.9


What's new in Connect2id server 7.9?

A major milestone in the multi-tenant edition is now complete -- isolation for all tenant configurations and data, except for the 100+ metrics. The expiration of objects was also revised, to take advantage of the availability of native TTL expiration in DynamoDB and also allow for fine-tuning.

Native DynamoDB expiration

In Connect2id server deployments in stateless cluster mode with a DynamoDB database the expiration of objects will now be done within DynamoDB. This will save read and write capacity units and hence money on your AWS bill as the server will no longer need to scan the tables for expired items and send out delete requests for them.

During startup the Connect2id server will automatically enable all tables with expiring items for DynamoDB TTL support. You don't need to configure anything in AWS for this, the server will do that for you.

Note that subject (end-user) sessions will continue to be expired from the Connect2id server, in case there are relying parties registered to receive OpenID Connect back-channel logout notifications.

However, if you don't have client applications registered for back-channel logout notifications, you can further optimise your bill by also enabling DynamoDB TTL expiration for the subject sessions. To do that set the following Java system properties:

// Enables TTL expiration in DynamoDB
dynamodb.enableTTL.sessionStore.sessionMap = true

// No expiration thread for end-user sessions
sessionStore.sessionMap.expirationInterval = 0

// No purge thread for orphaned subject index entries
sessionStore.internal.subjectIndexPurgeInterval = -1

If there are existing sessions in DynamoDB prior to enabling TTL they will not be automatically expired by DynamoDB because only newly created sessions will have the special "ttl" attribute. You can purge those sessions with a dedicated API call from the Connect2id server. Invoke the call after the Connect2id server upgrade, when time equal to the max lifetime of your sessions has elapsed. For example, if you switch to TTL expiration now and the max lifetime of your sessions is configured to be 1 week, call the purge command after 1 week has passed. This will ensure all pre-existing sessions have become ripe for expiration.

POST /session-store/rest/v2/purge?async=true HTTP/1.1
Authorization: Bearer ztucZS1ZyFKgh0tUEruUtiSTXhnexmd6

Session store updates

The session store received an update to enable fine tuning of expiration.

Sessions that are in memory or overflown / persisted to a database will be expired by the Connect2id every 5 minutes. With the new sessionStore.sessionMap.expirationInterval configuration setting you can change the interval, or turn off the expiration thread (if DynamoDB is going to take over the expiration job, as explained above).

There is also a new sessionStore.internal.subjectIndexPurgeInterval setting to override the default interval for purging orphaned entries in the subject index.

The purging of expired sessions and expired / invalid subject index entries can also be triggered manually, via the session store web API, with a new purge call.

POST /session-store/rest/v2/purge?async=true HTTP/1.1
Authorization: Bearer ztucZS1ZyFKgh0tUEruUtiSTXhnexmd6

Everything can now be configured via Java system properties

Two further configurations can now be set or overridden via Java system properties:

This completes the important roadmap milestone to enable all aspects of the Connect2id server to be configured via Java system properties.

Simplified configuration

To simplify the job of configuring the Connect2id server two settings were discontinued:


Infinispan was upgraded to the latest stable 9.4.11. You should now see increased performance, especially on scan operations that involve the backend database. The new Infinispan also comes with exciting new features which we intend to exploit in the next releases.

Multi-tenant edition

The multi-tenant edition of the Connect2id server now has complete logical isolation of all APIs and data, with exception of the monitoring endpoint, where tenant specific OpenID provider / OAuth 2.0 authorisation server metrics are not available yet (the metrics combine all tenants). In a next release tenants will be able to retrieve metrics for their own OpenID / OAuth 2.0 service and usage, while giving operations a separate set of metrics to monitor the system as a whole and its backends.

The tenant registry API was updated to allow a tenant to be disabled while keeping their configurations and data intact. When a tenant is deleted their persisted data will also be automatically deleted (previously this had to be performed manually).

The multi-tenant edition is currently only available to selected customers. If you wish to find out more about it write to us.

For details check out the release notes below.


To download a ZIP package of Connect2id server 7.9:

SHA-256: c3cbf574e8a401c7fd22243642235a442285ac1a9a5fc1aede4d36c219ab2f4c

As WAR package only:

SHA-256: 38d1c2ee807963cd3dcb5fd5a1838b38572a03c1c99d1a299a77ff417846f98a


Contact Connect2id support.

Release notes

7.9 (2019-04-01)


  • /WEB-INF/

    • Discontinues the op.authz.supportClaimsParam configuration property. The Connect2id server will always accept the optional "claims" OpenID authentication parameter and advertise its support in the OpenID provider metadata.
  • /WEB-INF/

    • Discontinues the authzStore.accessToken.jtiByteLength configuration property. All access tokens that are JWT-encoded will be issued with an eight-byte JWT identifier (jti).
  • /WEB-INF/

    • New optional sessionStore.internal.subjectIndexPurgeInterval configuration property. Sets the interval for purging orphaned subject index keys, in seconds. If -1 the purge thread is disabled. If 0 the Connect2id server will set the interval heuristically, depending on the Infinispan configuration (1 day for stateless deployments with Redis or DynamoDB, disabled in all other cases). If not specified the default value is 0.
  • /WEB-INF/

    • The definition of custom scope values that expand to a set of OpenID claims can now also be passed (or overridden) via Java system properties. The scope value is conveyed by the property name (with prefix to prevent clashes with other configuration properties); the property value a list of one or more claim names, separated by comma and / or space, to which the scope value expands.


  • /WEB-INF/

    • The definition of the compression dictionary for claim names in JWT-encoded access tokens can now also be passed (or overridden) via Java system properties. Prefix each claim name with to prevent clashes with other configuration properties.


  • /WEB-INF/infinispan-*.xml

    • Updates the Infinispan configurations to v9.4.

    • Where Infinispan-based expiration is enabled increases the thread wake-up interval from 60000 ms (1 minute) to 300000 ms (5 minutes).

    • Where Infinispan-based expiration of subject sessions (sessionStore.sessionMap) is configured, enables override of the expiration thread wake-up interval (from the default 300000 milliseconds, or 5 minutes, interval) via a sessionStore.sessionMap.expirationInterval Java system property. Setting the interval to 0 disables the expiration thread.

  • /WEB-INF/infinispan-*-stateless-redis-*.xml

    • Disables the Infinispan expiration thread (interval="0") for caches which keys are expired internally by Redis.
  • /WEB-INF/infinispan-stateless-dynamodb.xml

    • Enables automatic expiration of items by DynamoDB (via "ttl" attribute) for the following Infinispan caches / maps: sessionStore.subjectMap, authzStore.codeMap, authzStore.accessTokenMap, op.authSessionMap, op.consentSessionMap and op.clientRegTokenMap.

    • Automatic expiration of subject sessions by DynamoDB (via "ttl" attribute) can be enabled by setting the dynamodb.enableTTL.sessionStore.sessionMap Java system property to true and the sessionStore.sessionMap.expirationInterval Java system property to 0 (disables the Infinispan expiration thread for subject sessions). Expiration can be moved to DynamoDB if there are no relying parties registered for OpenID Connect back-channel logout notifications, as session expiration notifications can no longer be delivered to them.


      dynamodb.enableTTL.sessionStore.sessionMap = true
      sessionStore.sessionMap.expirationInterval = 0
  • /WEB-INF/infinispan-replication-dynamodb.xml

    • Enables automatic expiration of items by DynamoDB (via "ttl" attribute) for the following Infinispan caches / maps: sessionStore.subjectMap and authzStore.accessTokenMap.


  • /session-store/rest/v2/purge

    • Adds new resource to force a purge of expired subject sessions and expired and orphaned subject index entries. To initiate the purge POST to the resource using the configured access token for the session store web API (set by the sessionStore.apiAccessTokenSHA256 configuration property). The optional async=true query parameter will cause the purge to be done asynchronously.

      The purge call can be used when a Connect2id server deployment has switched to automatic DynamoDB expiration of sessions and there are pre-existing sessions without the "ttl" attribute that can be expired only by Infinispan.

      Example request to trigger a synchronous purge:

      POST /session-store/rest/v2/purge HTTP/1.1
      Authorization: Bearer ztucZS1ZyFKgh0tUEruUtiSTXhnexmd6
  • /monitor/v1/metrics

    • Adds new "sessionStore.sessionExpirationsWithoutData" meter. Meters the number of sessions expired by Infinispan where the session data was missing, resulting in a orphaned subject index entry that will need to be explicitly purged if not automatically expired by the store. See sessionStore.internal.subjectIndexPurgeInterval.

    • Adds new "sessionStore.subjectIndexPurgeTask" timer. Times the execution duration of the periodic task for purging orphaned subject index entries. If the purge thread is disabled the metric will appear with no data. See sessionStore.internal.subjectIndexPurgeInterval.

    • Removes the "clientStore.numCachedRegistrations" gauge which was deprecated in Connect2id server 6.1.

  • /tenants/rest/v1/{tid}/enabled

    • Adds new resource to retrieve or set a tenant's enabled status. The tenants registry web API is available only in the multi-tenant edition of the Connect2id server.

Resolved issues

  • Don't log redundant error_description for invalid_client errors at the token endpoint (OP 6201) (issue server/408).

  • Fixes a bug which prevented triggering of the JWT introspection response when the content type in the Accept header includes a parameter, such as charset=utf-8 (issue server/417). See draft-ietf-oauth-jwt-introspection-response-02.

  • Logs at INFO level client_id, token_endpoint_auth_method, grant_types and redirect_uris at new client registration (OP5181) and client update (OP5183) (issue server/419).

Dependency changes

  • Updates to Infinispan 9.4.11.Final.

  • Updates to com.nimbusds:tenant-manager:3.1

  • Updates to com.nimbusds:tenant-registry:3.0

  • Updates to com.nimbusds:oauth2-authz-store:10.1

  • Updates to com.nimbusds:oidc-session-store:10.4.1

  • Updates to com.nimbusds:oauth2-oidc-sdk:6.6.1

  • Updates to com.nimbusds:nimbus-jose-jwt:7.0.1

  • Updates to com.nimbusds:nimbus-jwkset-loader:3.1

  • Updates to com.nimbusds:common:2.32.1

  • Updates to org.bouncycastle:bcprov-jdk15on:1.61

  • Updates to org.bouncycastle:bcpkix-jdk15on:1.61

  • Updates to com.nimbusds:common:2.27.3

  • Updates to com.nimbusds:infinispan-cachestore-sql:3.1.2

  • Updates to com.nimbusds:infinispan-cachestore-dynamodb:3.3.1

  • Updates to com.nimbusds:infinispan-cachestore-ldap:3.1.1

  • Updates to com.unboundid:unboundid-ldapsdk:4.0.9

  • Updates to com.h2database:h2:1.4.198

  • Updates to org.mariadb.jdbc:mariadb-java-client:2.4.0

  • Updates to org.postgresql:postgresql:42.2.5

Device flow support in the OAuth 2.0 / OpenID Connect SDK


The device authorisation grant is now available in the OAuth 2.0 / OpenID Connect SDK, thanks to a contribution by Emond Papegaaij from Topicus KeyHub.

Also known as device flow, this is a special OAuth 2.0 grant intended for cases where the client resides on one device and the user gets authenticated and authorises the request on another.

Here are some typical scenarios:

  • The client is an IoT or smart home device which doesn't have a browser, but is capable of displaying a short code to the user, such as "WDJB-MJHT", or is able to transmit the code (e.g. via Bluetooth) to a smart phone or computer that belongs to the user.

  • The client, such as a smart TV or game console, is capable of launching a browser, but for reasons of convenience or security the client request is to be authorised on the user's smart phone or computer.

  • The client is a console / CLI or remotely accessed application.

The device flow

What are the steps in the device flow?

1. Device authorisation request and response

The client posts a request directly to the Authorisation server, specifying the scope (potentially implicitly) of the access token. The client can be public or confidential (authenticating itself with a credential).

POST /device-authz HTTP/1.1
Content-Type: application/x-www-form-urlencoded


The Authorisation server remembers the client request and responds with a unique device code, a user code and a few additional parameters required by the flow.

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store

  "device_code"               : "GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS",
  "user_code"                 : "WDJB-MJHT",
  "verification_uri"          : "",
  "verification_uri_complete" : "",
  "expires_in"                : 1800,
  "interval"                  : 5

2. User interaction

The client displays the user code along with a verification URI at the Authorisation server where the client is to be authorised, by letting the user type in the code.

The verification URI with the code could also be encoded in a QR code.

After the Authorisation server successfully verifies the user code, the user is presented with a consent screen to authorise or deny the client request.

3. Token request

During the user interaction the client continuously polls the token endpoint of the Authorisation server with the device code:

POST /token HTTP/1.1
Content-Type: application/x-www-form-urlencoded


If the user interaction has not completed the Authorisation server will return an authorization_pending error code, to signal the client to repeat the token request after the suggested interval (returned in the device authorisation response):

HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

  "error" : "authorization_pending"

The client stops the polling when the Authorisation server returns one of the following responses:

  • The request was authorised by the user, the Authorisation server provides the requested token(s):

    HTTP/1.1 200 OK
    Content-Type: application/json;charset=UTF-8
    Cache-Control: no-store
    Pragma: no-cache
    "token_type"    : "Bearer",
    "access_token"  : "2YotnFZFEjr1zCsicMWpAA",
    "expires_in"    : 3600,
    "refresh_token" : "tGzv3JOkF0XG5Qx2TlKWIA",
    "scope"         : "post_stats"
  • The request was denied by the user:

    HTTP/1.1 400 Bad Request
    Content-Type: application/json;charset=UTF-8
    Cache-Control: no-store
    Pragma: no-cache
    "error" : "access_denied"
  • The device code has expired:

    HTTP/1.1 400 Bad Request
    Content-Type: application/json;charset=UTF-8
    Cache-Control: no-store
    Pragma: no-cache
    "error" : "expired_token"

SDK usage

The Java classes for implementing the device authorisation grant on the client and server side are found in the com.nimbusds.oauth2.sdk.device package.

Example device authorisation request:

// Create the device authZ requst and post it to the AS
URI deviceAuthzURI = new URI("");
ClientID clientID = new ClientID("123");
Scope scope = new Scope("post_stats");

HTTPRequest httpRequest = new DeviceAuthorizationRequest.Builder(clientID)

HTTPResponse httpResponse = httpRequest.send();

// Parse the response
DeviceAuthorizationResponse response = DeviceAuthorizationResponse.parse(httpResponse);

if (! response.indicatesSuccess()) {
    System.out.println("Error: " + response.getErrorObject());

DeviceAuthorizationSuccessResponse successResponse = response.toSuccessResponse();

System.out.println("Device code: " + successResponse.getDeviceCode());
System.out.println("User code: " + successResponse.getUserCode());

Release notes

version 6.6 (2019-03-19)

  • Adds new com.nimbusds.oauth2.sdk.device package implementing the OAuth 2.0 Device Authorization Grant (draft-ietf-oauth-device-flow-15).