Connect2id server 9.1 updates JWT-secured token introspection responses

This release of the Connect2id server updates support for JWT Response for OAuth Token Introspection to the upcoming version 09. This OAuth 2.0 extension is intended for securing token introspection results with a digital signature, which is intended for business cases where the identity provider assumes liability for the content of the token. One such case is services using verified person data to create digital certificates, which in turn are used to create qualified electronic signatures (QES).

What changes were made in version 09?

  • The content of the token introspection response was moved to a separate JWT claim called token_introspection. This is done to prevent potential confusion and clashes of token introspection response parameters with top-level JWT claims that bear the same name.

  • The following top-level JWT claims are now made mandatory:

    • iss -- Set to the Connect2id server issuer URL.
    • aud -- Set to the client_id of the introspection endpoint caller (typically a resource server inspecting a token).
    • iat -- Set to the issue timestamp.
    • token_introspection -- JSON object containing the token introspection response mentioned above.
  • The JWT-secured response is triggered by an Accept HTTP request header set to application/token-introspection+jwt, unless op.token.introspection.alwaysRespondWithJWT is enabled, when the Accept header will be ignored and the response will always be JWT-secured.

Example request, the client (the resource server) authenticates at the introspection endpoint with basic authentication, using its registered client_id and client_secret. Notice the Accept header:

POST /token/introspect HTTP/1.1
Host: c2id.com
Content-Type: application/x-www-form-urlencoded
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Accept: application/token-introspection+jwt

token=giuLtTTnya5XpHVKNopT9w.gepM14CKpHcWloJ3XqMtvA

Example response with a signed JWT in the body:

HTTP/1.1 200 OK
Content-Type: application/token-introspection+jwt

eyJraWQiOiJ3RzZEIiwidHlwIjoidG9rZW4taW50cm9zcGVjdGlvbitqd3QiLCJhbGc
iOiJSUzI1NiJ9.eyJpc3MiOiJodHRwczovL2FzLmV4YW1wbGUuY29tLyIsImF1ZCI6I
mh0dHBzOi8vcnMuZXhhbXBsZS5jb20vcmVzb3VyY2UiLCJ0b2tlbl9pbnRyb3NwZWN0
aW9uIjp7ImFjdGl2ZSI6dHJ1ZSwiaXNzIjoiaHR0cHM6Ly9hcy5leGFtcGxlLmNvbS8
iLCJhdWQiOiJodHRwczovL3JzLmV4YW1wbGUuY29tL3Jlc291cmNlIiwiaWF0IjoxNT
E0Nzk3ODIyLCJleHAiOjE1MTQ3OTc5NDIsImNsaWVudF9pZCI6InBhaUIyZ29vMGEiL
CJzY29wZSI6InJlYWR3cml0ZWRvbHBoaW4iLCJzdWIiOiJaNU8zdXBQQzg4UXJBangw
MGRpcyIsImJpcnRoZGF0ZSI6IjE5ODItMDItMDEiLCJnaXZlbl9uYW1lIjoiSm9obiI
sImZhbWlseV9uYW1lIjoiRG9lIiwianRpIjoidDFGb0NDYVpkNFh2NE9SSlVXVlVlVF
pmc0toVzMwQ1FDcldERGp3WHk2dyJ9fQ.d1XLA-X8Inb0kwvRkk10ZokWbpEAO6u4Vb
0kirVPOLUdo2KiKD1IGer6bcVp-pNc2eC1yyUZGBp5GIDey8qhc41Oyhn6TOUAkLzZM
u2vAC7j4EsTM7-pKkbWX1kmH84-vAGvLR0MNWtVUgLmmIOy9krUMXE1jd0IS_Iqk7xW
JxmZLbuLHXx92LXRdErwThO-AHVLkiqIlz08H4LAsnKPVKMouzqBFYwK050ZJbnaVYw
O-QRC-lhCR_8JnsLZVp-QilDeWkOJiJ46un5HKZSYwxMjkhMs_Py8GOQaQk0ZY4MGCe
gTCKyiOsEIYSuIIDLy4YbHtY14SvZOUQwPDneFxQ

Example decoded JWT header, using the same JWS algorithm and key as for self-contained (JWT) access tokens:

{
  "alg" : "RS256",
  "typ" : "5iKs",
  "kid" : "token-introspection+jwt"
}

Example decoded JWT claims, notice how the introspection members are now encapsulated in a container claim:

{
  "iss"                 : "https://c2id.com/",
  "aud"                 : "kengo6Bo",
  "token_introspection" : { "active"    : true,
                            "iss"       : "https://c2id.com/",
                            "aud"       : "kengo6Bo",
                            "iat"       : 1514797822,
                            "exp"       : 1514797942,
                            "client_id" : "paiB2goo0a",
                            "scope"     : "openid email profile",
                            "sub"       : "c5787848-d360-42fa-b01f-558b8f33506c",
                            "jti"       : "doRu8eeNg0geew7u" }
}

The legacy JWT-secured introspection response from draft-ietf-oauth-jwt-introspection-response-08 can still be triggered, by setting the Accept header to application/jwt:

POST /token/introspect HTTP/1.1
Host: c2id.com
Content-Type: application/x-www-form-urlencoded
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Accept: application/jwt

token=giuLtTTnya5XpHVKNopT9w.gepM14CKpHcWloJ3XqMtvA

Download

To download a ZIP package of Connect2id server 9.1:

https://connect2id.com/assets/products/server/download/9.1/Connect2id-server.zip

SHA-256: 80d252bc3a1a966bee9abdaeb079b5b1a0f1e11c8c2d1bf5a6ae97c038421995

As WAR package only:

https://connect2id.com/assets/products/server/download/9.1/c2id.war

SHA-256: eb547fd5a7eecc804980c367b556808639c2665e294fd4c1eb03c08ad4e128b0

Questions?

Contact Connect2id support.


Release notes

9.1 (2020-03-24)

Web API

  • /token/introspect

    • Updates "JWT Response for OAuth Token Introspection" support to the upcoming draft-ietf-oauth-jwt-introspection-response-09 version.

      For a client (resource server) to obtain a JWT-secured introspection response it must submit an introspection request with the Accept HTTP request header set to "application/token-introspection+jwt". The request must be authorised with the registered client authentication method or with an access token.

      The JWT response will be JWS signed and include the following JWT claims:

      • "iss" -- Set to the OpenID Provider / Authorisation server issuer URL.
      • "aud" -- Set to the client_id of the caller (resource server).

      • "iat" -- The issue timestamp.

      • "token_introspection" -- A JSON object containing the token introspection response members, such as "active", etc.

      The optional op.token.introspection.jwtType configuration property that overrides the JWT "typ" (type) header applies.

      Legacy JWT-secured introspection responses (according to draft-ietf-oauth-jwt-introspection-response-08) will continue to be supported, for a client (resource server) to request one the Accept HTTP request header must be set to "application/jwt".

SPI

Upgrades the Connect2id server SDK to com.nimbusds:c2id-server-sdk:4.19

  • com.nimbusds.openid.connect.provider.spi.par.ValidatorContext

    • Adds a getIssuer() method to the PAR ValidatorContext.

Dependency changes

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

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