Connect2id server 15.0 upgrades to Java 17, adds a refresh token maximum idle timeout
2024 begins with a new major release of the Connect2id server which was in silent preparation for several months.
Runtime changes
The server is now built for Java 17, meaning the Java 11 runtime is no longer supported. The most recent Java LTS runtime, 21, has not been tested and therefore isn’t marked as supported yet. We intend to test it once Apache Tomcat 11 with virtual threads support (project Loom) ships a stable release.
The Servlet APIs and related dependencies were also upgraded, to the latest Jakarta Servlet 6.0 API. This means that the Connect2id server will now require Apache Tomcat 10.1 to run. Tomcat 9, which is based on the older Java Servlet APIs, can no longer be used.
The c2id/c2id-server-min Docker image was updated to reflect this changes. Note that the stock image for Tomcat 10.1 has switched to the Eclipse Temurin Java SE build and uses Ubuntu Linux as the underlying Linux distribution. The older Tomcat 9 image was based on Amazon’s Corretto image.
New refresh token capabilities
The refresh token in OAuth 2.0 enables client applications to receive a long-term credential for accessing protected resources. The credential can be issued with indefinite validity (and revoked when required), or issued with an a set expiration time. When the refresh token becomes invalidated, due to revocation or end of its lifetime, the client application can no longer use it at the token endpoint, indicated by an invalid_grant error, which means the end-user must be asked to authorise the client again.
This Connect2id server release introduces an additional time dimension to refresh tokens – the ability to set an maximum idle time.
Refresh token max idle time
By configuring the refresh tokens for a client with a suitable maximum idle time, a session for the client and the end-user is established at the token endpoint. As long as the client keeps using the refresh token it will remain valid and will grant the issue of new access tokens. When use of the refresh token stops, due to the end-user leaving the client application or due to inactivity, and the maximum idle time is reached, the refresh token becomes invalidated. In order to continue use of the application, the end-user must re-authenticate and re-authorise the client (unless the consent was persisted).
This new refresh token property is set using the optional
refresh_token.max_idle
parameter of the
consent object. The
value is expressed in seconds, with zero being the default and meaning no
maximum idle time.
Example setting of a 1 hour idle time:
{
"scope" : [ "openid", "email" ],
"claims" : [ "email", "email_verified" ],
"refresh_token" : { "issue" : true,
"max_idle" : 3600 }
}
The maximum idle time can be combined with a lifetime limit of the refresh token. The refresh token will become invalidated when one or the other timeout occurs. The maximum idle time should be shorter than the lifetime limit.
Example setting of a 1 week lifetime limit and a 1 hour idle time for the refresh token:
{
"scope" : [ "openid", "email" ],
"claims" : [ "email", "email_verified" ],
"refresh_token" : { "issue" : true,
"lifetime" : 604800,
"max_idle" : 3600 }
}
New refresh_token_expires_in token response parameter
The token response of the
Connect2id server was also updated and will now include a
refresh_token_expires_in
parameter, whenever a refresh token with a lifetime
limit is issued. Refresh tokens that don’t have a lifetime limit, or have
maximum idle time only, will not include this parameter. A client may use this
hint to make an authorisation request to the Connect2id server ahead of the
refresh token expiration.
{
"access_token" : "vJkbPNUFaK4kVIMGQlEmyA.-MAquq_5yQqtae62b8i7aw",
"token_type" : "Bearer",
"expires_in" : 600,
"scope" : "openid email",
"refresh_token" : "eyJraWQiOiIxZTlnZGs3IiwiYWxnIjoiUl...",
"refresh_token_expires_in" : 604800
}
The invalid_grant
error code remains the standard and recommended method for
clients to detect when the refresh token has become invalid, due to expiration
or revocation.
Access token lifetime guarantees
The refresh token as an OAuth grant is used to mint new access tokens and when it’s given a certain time limit descendant access tokens should not exceed it.
This can occur when a refresh token that is configured for expiration approaches it end of life, which may then become shorter that the configured access token lifetime. To prevent this from occurring the Connect2id server will automatically trim the access token lifetime to the (remaining) lifetime of the refresh token, or the maximum idle time of the refresh token (whichever is shorter).
The above token example token response may get modified as follows when the remaining refresh token lifetime becomes shorter than the originally configured access token lifetime of 600 seconds:
{
"access_token" : "vJkbPNUFaK4kVIMGQlEmyA.-MAquq_5yQqtae62b8i7aw",
"token_type" : "Bearer",
"expires_in" : 550,
"scope" : "openid email",
"refresh_token" : "eyJraWQiOiIxZTlnZGs3IiwiYWxnIjoiUl...",
"refresh_token_expires_in" : 550
}
Refresh token introspection updates
The Connect2id server
resource for
inspecting refresh tokens will now provide a more exact picture of the token.
The rti
(refresh token issue time) will be reported consistently for both
refresh tokens linked to long-lived authorisations as well as self-contained
(JWT-encoded) refresh tokens linked to transient authorisations. The rtl
(refresh token lifetime) will report the actual remaining token lifetime,
relative to the refresh token issue time, rather than the originally
configured. The new refresh token maximum idle time property is going to appear
as rtm
when set.
Connect2id server SDK
The current Connect2id server SDK version is now 5.1. Starting with v5.0 it is being built with Java 17, which becomes the minimum JDK requirement for developing new server plugins in future.
The RefreshTokenSpec
was updated to support the new max_idle
parameter.
There are no breaking changes in the server SDK, save for
InitContext.getServletContext.
which will now return a jakarta.servlet.ServletContext
instead of a
javax.servlet.ServletContext
. This interface method is rarely used, but if
you do happen to have a plugin that relies on it update it accordingly to the
new Jakarta Servlet 6.0 API.
Other changes and fixed bugs
The op.idToken.ignoreUserInfoError configuration property was deprecated. If you rely on it to require ID token issue to fail on claims source exceptions use the new op.idToken.ignoreClaimsSourceErrors instead.
The SQL connection pool
metrics will
now be published under the sqlStore.pool.*
prefix, rather than taking the
name of the first Infinispan map / cache as the prefix, for ease and
consistency.
A handful of bugs, some more serious, some less (but none critical) were also fixed in this release. You can find detailed information in the release notes below.
Upgrading to Connect2id server 15.0
-
Make sure the new Connect2id server is deployed in a Java 17 runtime.
-
Make sure the Servlet container is Jakarta Servlet 6.0 compliant. The compliant Apache Tomcat version is 10.1.
-
Database schema changes:
This new release requires an upgrade to the SQL database schema of existing deployments.
In order to support the new
max_idle
refresh token property thelong_lived_authorizations
SQL table, part of the Connect2id server authorisation store, received a newrtm
column. The schema upgrade will be performed automatically for existing deployments, on Connect2id server 15.0 startup, unless the server is intentionally configured withdataSource.createTableIfMissing=false
, in which case the column addition to upgrade the table schema must be done manually.All SQL table definitions can be found in
/WEB-INF/sql/create-table-statements-*.sql
, where*
identifies the database type, e.g.postgres95
for PostgreSQL.Deployments with DynamoDB, which is essentially a schema-less database, do not require a schema upgrade operation.
Download 15.0
For the signature validation: Public GPG key
Standard Connect2id server edition
Apache Tomcat package with Connect2id server 15.0: Connect2id-server.zip
GPG signature: Connect2id-server.zip.asc
SHA-256: 7ca4a6699ed7bc014069ae1d830cbd28f706e81987c427ad834e8e6fea1f407c
Connect2id server 15.0 WAR package: c2id.war
GPG signature: c2id.war.asc
SHA-256: 7d02b3f3bae9988815c340c9c49b69a1a28ecdc53c87118ff713dc58191ceab7
Multi-tenant edition
Apache Tomcat package with Connect2id server 15.0: Connect2id-server-mt.zip
GPG signature: Connect2id-server-mt.zip.asc
SHA-256: 75f15bff04792af288e6669e1e254f2acc2c5c04c4f9ef1d5ba53308e0274127
Connect2id server 15.0 WAR package: c2id-mt.war
GPG signature: c2id-mt.war.asc
SHA-256: 26b2d23114a17999e31bfba27cb3aa3893b1d9c62b8b284373ea4bb610301e2f
Questions?
For technical questions about this new release contact Connect2id support. To purchase a production license for the Connect2id server, renew or upgrade your support and updates subscription, email our sales.
Release notes
15.0 (2024-01-02)
Summary
-
Upgrades to Java 17.
-
Upgrades to Jakarta Servlet 6.0 and Jakarta JAX-RS 3.1. The minimum supported Apache Tomcat version becomes 10.1.x.
-
The Connect2id server SDK (v5.0) is upgraded to Java 17 and Jakarta Servlet 6.0. Plugins that retrieve a
ServletContext
from theInitContext
interface will receive ajakarta.servlet.ServletContext
instead of ajavax.servlet.ServletContext
. -
Refresh tokens issued by the Connect2id server can be optionally set to expire after a period of idle time, expressed in seconds. This enables an identity provider to establish a session for a given end-user and client application, with the refresh token remaining active as long as the client keeps using it frequently enough to obtain new tokens. When use of the refresh token stops, due to the end-user leaving the client application, and the maximum idle time is reached, the refresh token becomes invalidated. The client application must make a new authorisation request, to log in the end-user and / or obtain their consent, in order to receive a new refresh token.
The refresh token maximum idle time is settable per end-user and / or client, can be applied to both regular and rotated refresh tokens, and is disabled by default. The refresh token maximum idle time is independent of the optional refresh token lifetime setting, and should not exceed it.
-
For token responses containing an access and refresh token, the lifetime of the access token will be automatically trimmed so that it doesn’t exceed the maximum idle time or lifetime of the refresh token, whichever is shorter.
Configuration
-
/WEB-INF/oidcProvider.properties
- op.idToken.ignoreClaimsSourceErrors – New optional configuration
property, deprecating the existing
op.idToken.ignoreUserInfoError
which will be removed in a future major Connect2id server release.
- op.idToken.ignoreClaimsSourceErrors – New optional configuration
property, deprecating the existing
-
/WEB-INF/infinispan-*-{mysql|oracle|postgres95|sqlserver}.xml
-
Sets the HikariCP property “poolName” to
sqlStore
so that all SQL connection pool related metrics appear under thesqlStore.*
prefix instead of the name of the first declared Infinispan map / cache (sessionStore.subjectMap
in the regular Connect2id server edition, ortenantRegistry.tenants
in the multi-tenant Connect2id server edition). -
Upgrades the SQL schema by adding a new
rtm
(refresh token maximum idle time) column to thelong_lived_authorizations
table. In existing deployments the Connect2id server will automatically add the new column on startup, unlessdataSource.createTableIfMissing
is disabled.
-
Web API
-
/authz-sessions/rest/v3/
- The consent object receives a new optional
refresh_token.max_idle
parameter. May be used to specify a maximum idle time, in seconds, for the issued refresh token. If the refresh token is not used within this time period the Connect2id server will invalidate it due to inactivity. The default value is0
(no idle time expiration).
- The consent object receives a new optional
-
/direct-authz/rest/v2
- The request object receives a new optional
refresh_token.max_idle
parameter. May be used to specify a maximum idle time, in seconds, for the issued refresh token. If the refresh token is not used within this time period the Connect2id server will invalidate it due to inactivity. The default value is0
(no idle time expiration).
- The request object receives a new optional
-
/token
-
The token response will include a
refresh_token_expires_in
parameter for responses that contain a refresh token that is set to expire. When present the value is a positive integer indicating the number of seconds until the refresh token expiration, similar to the standard access tokenexpires_in
parameter. Responses with refresh tokens that don’t have a maximum lifetime set will not include this parameter. Clients can use this parameter as a hint when to make a new request to the Connect2id server authorisation endpoint. Theinvalid_grant
error code remains the standard and recommended method for clients to detect when the refresh token has become invalid, due to expiration or revocation. -
For token responses with an expiring refresh token, the lifetime of the issued access token is guaranteed to never exceed the lifetime or the maximum idle time of the refresh token. If the lifetime of the access token would exceed the refresh token lifetime or maximum idle time, it will be automatically trimmed to achieve expiration parity with the refresh token.
-
-
/authz-store/rest/v3/authorizations
- The OAuth 2.0 / OpenID Connect authorisation object receives a new
optional
rtm
member, representing the refresh token maximum idle time, in seconds. The default value is0
(no idle time expiration).
- The OAuth 2.0 / OpenID Connect authorisation object receives a new
optional
-
/monitor/v1/metrics
- All SQL store Hikari connection pool metrics are now published under the
sqlStore.pool.*
prefix. The[infinispan-cache-name].sqlStore.pool.*
prefix is no longer used.
- All SQL store Hikari connection pool metrics are now published under the
SPI
-
Upgrades the Connect2id server SDK to com.nimbusds:c2id-server-sdk:5.1
-
Upgrades to Java 17.
-
The
InitContext.getServletContext()
method returnsjakarta.servlet.ServletContext
instead ofjavax.servlet.ServletContext
(breaking change). -
The
ServletInitContext
constructor acceptsjakarta.servlet.ServletContext
instead ofjavax.servlet.ServletContext
(breaking change). -
The
RefreshTokenSpec
adds support for setting a maximum idle time for the refresh token.
-
Resolved issues
-
Fixes the HTML representation of the static pages for HTTP 404, 405, 500 and all other errors that aren’t handled by the web application (issue server/953).
-
Removes support for legacy
cnf.x5t
encoding in access tokens issued by Connect2id server 7.x and older releases (issue authz-store/229). -
The access token lifetime must be automatically trimmed to match the lifetime or the remaining lifetime of the refresh token (for expiring refresh tokens)(issue authz-store/228).
-
The
rtl
(refresh token lifetime) value of authorisation objects returned by the authorisation store web API must reflect the remaining lifetime in respect torti
(refresh token issue time) when the refresh token was configured for rotation (issue authz-store/224). -
The
rti
(refresh token issue time) value for long-lived authorisation objects with configured rotation must be updated after a refresh (issue authz-store/224). -
The expiration time of self-contained (JWT-encoded) refresh tokens must not be advanced when the refresh token is set for rotation and a new refresh token is returned at the token endpoint in response to a refresh token grant (issue authz-store/225).
-
Removes the /client-reg/* endpoint alias to /clients/* that was deprecated in Connect2id server 3.0 (2015-03-26) (issue server/911).
-
Removes the authorisation store and session banner pages (issue server/763).
-
The SQL store ExpiredEntryPagedReaper must log the IS0128 debug message in all execution paths (issue sql-store/37).
-
Fixes the Infinispan metadata recreation for authorisation code entries persisted to an SQL database. The bug was introduced in Connect2id server 9.1.1 in response to issue authz-store/176 and caused expired entries to remain persisted in the “pending_codes” table (issue authz-store/230).
Dependency changes
-
Upgrades to com.nimbusds:c2id-server-sdk:5.1
-
Updates to com.nimbusds:oauth2-oidc-sdk:11.9
-
Updates to com.nimbusds:c2id-server-property-source:2.0
-
Updates to com.nimbusds:tenant-manager:9.0.2
-
Updates to com.nimbusds:tenant-registry:9.0
-
Upgrades to com.nimbusds:oauth2-authz-store:26.2.1
-
Upgrades to com.nimbusds:oidc-session-store:17.1
-
Updates to com.nimbusds:oauth-grant-handlers-web:2.0
-
Updates to com.nimbusds:nimbus-jwkset-loader:6.0
-
Updates to com.nimbusds:content-type:2.3
-
Upgrades to com.nimbusds:common:3.0.3
-
Updates to com.thetransactioncompany:cors-filter:3.0
-
Updates to Infinispan 14.0.21.Final
-
Updates to com.nimbusds:infinispan-cachestore-common:4.0
-
Updates to com.nimbusds:infinispan-cachestore-sql:8.1.1
-
Updates to com.nimbusds:infinispan-cachestore-dynamodb:6.0
-
Updates to com.nimbusds:infinispan-cachestore-redis:11.0
-
Upgrades to Jakarta Servlet API 6.0.0
-
Upgrades to JAX-RS 3.1
-
Upgrades to Jersey 3.1.4
-
Updates to DropWizard Metrics 4.2.23
-
Updates to commons-io:commons-io:2.15.0
-
Updates to org.apache.commons:commons-compress:1.24.0
-
Updates to org.mariadb.jdbc:mariadb-java-client:2.7.11