Connect2id server 4.1

This is a maintenance release of the OpenID Connect server which deals with data replication errors when Infinispan (the data grid layer) selects an incorrect serialiser version for a session or other object that needs to be transported across a Connect2id cluster.

If your Connect2id server cluster is affected you will be seeing serialisation errors in your logs at node startup or when performing a live roll-over from a 3.x cluster to the latest 4.x release.

The exceptions may look like this:

org.infinispan.commons.CacheException: Unable to invoke method public void org.infinispan.statetransfer.StateTransferManagerImpl.waitForInitialStateTransferToComplete() throws java.lang.Exception on object of type StateTransferManagerImpl

or

java.io.UTFDataFormatException: Invalid byte
        at org.jboss.marshalling.UTFUtils.readUTFBytes(UTFUtils.java:173) ~[infinispan-embedded-7.2.5.Final.jar:?]
        at org.jboss.marshalling.river.RiverUnmarshaller.readUTF(RiverUnmarshaller.java:1833) ~[infinispan-embedded-7.2.5.Final.jar:?]

The replication error may also manifest as some other exception.

Upgrading to 4.1

Download the 4.1 package and make sure the infinispan.xml configuration is updated to include a new externaliser declaration (see the release notes for more info).

Basically, replace the lines

<advanced-externalizer class="com.nimbusds.sessionstore.impl.ext.SubjectSessionExternalizerV1"/>
<advanced-externalizer class="com.nimbusds.sessionstore.impl.ext.SubjectSessionExternalizerV2"/>

with

<advanced-externalizer class="com.nimbusds.sessionstore.impl.ext.SubjectSessionExternalizer"/>

Unfortunately, the nature of the fix is such that a live automatic roll-over to 4.1 is not possible. To mitigate we extended the session store web API to allow creation of new sessions with a preset identifier (SID). With that an external job can be set up to copy existing user sessions from the old to the new cluster:

  1. Get the active user sessions from your current cluster with

    GET /session-store/rest/v2/sessions HTTP/1.1
    Host: c2id.com
    Authorization: Bearer ztucZS1ZyFKgh0tUEruUtiSTXhnexmd6
    
  2. Then recreate them in the new 4.1 cluster with

    POST /session-store/rest/v2/sessions HTTP/1.1
    Host: c2id.com
    Authorization: Bearer ztucZS1ZyFKgh0tUEruUtiSTXhnexmd6
    SID: session-id
    Content-Type: application/json
    
    {
      "session-data"  : "..."
    }
    

Download

To download a ZIP package of Connect2id server 4.1:

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

As WAR package only:

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

Questions?

Get in touch Connect2id support, we'll be delighted to help out.


Release notes

4.1 (2016-03-04)

Configuration

  • /WEB-INF/infinispan.xml

    • Replaces the advanced externaliser classes com.nimbusds.sessionstore.impl.ext.SubjectSessionExternalizerV1 and com.nimbusds.sessionstore.impl.ext.SubjectSessionExternalizerV2 with com.nimbusds.sessionstore.impl.ext.SubjectSessionExternalizer (see issue session-store/27).

Web API

  • Session Store API /session-store/rest/v2:

    • The POST method adds support for an optional "SID" header to allow creation of new subject (end-user) sessions with a predefined session identifier (SID). Intended to assist migration of sessions (issue session-store/28).
  • Session Store API /session-store/rest/v2/sessions/count:

    • Modifies the behaviour of the GET method to only return the number of session present in memory, in order to avoid hitting the cache loader (in cases where the session store is configured to overflow or backup sessions to disk) (issue session-store/29).

Bug fixes

  • Fixes a serialisation bug that affected Infinispan replication of subject (end-user) sessions between Connect2id server nodes due to non-deterministic selection of versioned serialisers for session objects by Infinispan (issue session-store/27). The bug fix necessitated changes to the Infinispan configuration (see above). Live roll-over from previous Connect2id server versions to 4.1 will not migrate existing end-user sessions automatically; these may however be copied by an external job via the updated session store web API.

Dependencies

  • Upgrades to com.nimbusds:oidc-session-store:3.4.2

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

  • Upgrades to com.nimbusds:oauth2-oidc-sdk:5.5.1

  • Upgrades to org.glassfish.jersey.containers:jersey-container-servlet:2.22.1

OpenID Connect client library for iOS

Integrating OpenID Connect login into iOS apps has just become easier. Developers can now make use of the AppAuth toolkit, created by Google and recently open sourced and contributed to the OpenID Foundation.

The toolkit is standards compliant, works with iOS 7+, and follows the best current practises:

  • The user is presented to the IdP login page in a web view that is controlled by the browser (SFSafariViewController), instead of using the traditional web view embedded into the app itself (UIWebView). This prevents the app from snooping on the user's login credentials, and also enables users to benefit from the browser password manager.

  • The callback URIs for receiving the OpenID authentication response from an IdP can use custom schemes, or Universal Links.

  • Support for the PKCE security extension for public clients.

Maintainers of the project are William Dennis and Steven Wright.

You can watch Williams's talk at the OpenID Summit in Tokyo last year where he presents the AppAuth project.

tubeembed

Public client support with PKCE added to the OpenID Connect client for developers

The OpenID Connect client for test driving IdP servers, including ours, received a bunch of improvements and can now pose as an unauthenticated (public) client, with optional PKCE security.

With that you can now choose between the following client authentication methods:

  • client_secret_basic -- The default HTTP basic authentication
  • client_secret_post -- Like basic, but using HTTP post instead of the Authorization header to submit the client credentials
  • client_secret_jwt -- Client authentication by means of a HMAC JWT assertion.
  • none -- For public clients.

Client authentication in OpenID Connect is defined in section 9 of the OpenID Connect Core 1.0 spec.

If you're not familiar with the dev client, you can try it out on our demo server. The UI is simple and intuitive. There are just three panes:

1. Set the OpenID provider endpoints

alt text

Simple form to enter the OpenID Provider (OP) endpoints. If the OP supports discovery, you can just enter the OP's URL and the client will automatically fetch the discovery JSON and populate the required parameters.

2. Set the client credentials and callback

alt text

Enter the client or Relying Party (RP) credentials and callback URI. For a public client select none in the client authentication dropdown list. Then you have the option to enable PKCE as well.

3. Make the actual request

alt text

With all required provider and client details in place, you can now make the actual OpenID authentication request by triggering a redirect to the IdP via a browser popup window. You have all key request parameters to play with - the requested scope, the response type (for code, implicit or hybrid flow) and prompt.

4. Receive and process the token(s)

alt text

The OpenID server will respond by invoking the registered callback for the client. You can see a breakdown of the code-for-token exchange (in case you requested a code flow), and retrieving the requested claims from the UserInfo endpoint.

The ID token will also be verified and its content displayed.


Download

If you want to install the dev OpenID Connect client on your own computer or server download a ready WAR package for the latest 1.4 version:

https://bitbucket.org/connect2id/openid-connect-dev-client/downloads

From the Git repo you can also obtain the source code. If you wish to contribute, just drop us an email (to Connect2id support), or submit a pull request.

This is our wishlish:

  • Support for private_key_jwt client authentication.

  • Support for the claims, id_token_hint and other optional OpenID parameters.

  • Form for dynamic client registration.

Identity and access token impersonation in Connect2id server 4.0

Impersonation and delegation

The 4th major release of the Connect2id server introduces support for impersonation and delegation, two key features for tackling advanced use cases in OAuth and OpenID Connect.

  • Impersonation -- enables a privileged user to log into a client application under a different identity. May also extend to accessing protected protected resources (web APIs) as the impersonated identity and using their permissions. The Connect2id server supports impersonation by issuing ID, access and refresh tokens with a subject that differs from the currently logged-in user.

  • Delegation -- enables one user to act on behalf of another. Delegation is effectively supported by the same means - by issuing tokens that bear the identity of the delegated user as their subject.

Setting the impersonated subject in the code and implicit flows

How to impersonate or delegate a user in the code and implicit flows?

Upon detection of a privileged user at the login page, provide them with the option to log into the requesting application under a different identity. This can be implemented as a suitable UI control in the consent screen to permit selection of a target user identity to be impersonated.

If impersonation is chosen, simply add the subject identifier of the target user using the new impersonated_sub parameter of the consent object that is sent to the authorisation session endpoint of the Connect2id server.

Example: To login a privileged user as the end-user claire:

{
  "scope"            : [ "openid" ],
  "impersonated_sub" : "claire"
}

Example: To login a privileged user as the end-user claire and also obtain an impersonated access token for her for the listed email scope and its associated claims:

{
  "scope"            : [ "openid", "email" ],
  "claims"           : [ "email", "email_verified" ],
  "impersonated_sub" : "claire"
}

The Connect2id server will then proceed to issue the requested ID / access / token(s) for the impersonated user.

Maintaining an impersonated session with an OpenID client

OpenID Connect clients that have logged in an impersonated user may periodically check that the user is still logged in with the IdP by obtaining a new ID token. This may be done via a prompt=none request (the recommended method) or by simply repeating the original request.

In such cases it's important to detect any such subsequent OpenID authentication requests as following up from an original request that has gone through impersonation. If that doesn't happen the IdP will return an ID token for the original user (impersonator), and in case of incremental consent, the access / refresh token subject will also be affected.

To maintain impersonated sessions with an OpenID client continuously, the Connect2id server expects the client to make use of the optional id_token_hint parameter. This parameter is defined in the OpenID spec and has the following meaning:

id_token_hint OPTIONAL. ID Token previously issued by the Authorization Server being passed as a hint about the end-user's current or past authenticated session with the client. [...]

Example OpenID authentication request with an ID token hint:

https://openid.c2id.com/login?
    response_type=code
    &scope=openid%20email
    &client_id=000123
    &state=af0ifjsldkj
    &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
    &id_token_hint=eyJhbGciOiJSUzI1NiIsImtpZCI6InMxIn0.eyJlf9Jf...

The Connect2id server will check the ID token hint for a special act claim (see next section) as an indicator whether the impersonation is being implied. If that's detected it will also notify the login page via the authentication and consent prompts (if these get invoked) by setting the impersonated_sub parameter.

This parameter is also new, and if set will specify the ID of the impersonating user.

{
  "type"             : "consent",
  "sid"              : "g6f5K6Kf6EY11zC00errCf64yLtg9lLANAcnXQk2xUE",
  "display"          : "popup",
  "impersonated_sub" : "claire",
  "sub_session"      : { ... },
  "client"           : { ... },
  "scope"            : { ... },
  "claims"           : { ... }
}

In the ideal case no additional parameter should be required to maintain an impersonated session, so we're brainstorming on a alternative way to do that. Hopefully that will become possible in a future release. Stay tuned!

Identifying impersonated ID and access tokens

How can you tell that an ID or access token is impersonated?

Tokens whose subject (end-user) is changed will bear the same attributes as regular ones, save for the act (actor) attribute which signals that there is impersonation / delegation going on.

Example JWT claims set of an impersonated ID token indicating that a privileged user admin is impersonating user claire:

{ 
  "iss" : "https://openid.c2id.com",
  "sub" : "claire",
  "aud" : "000123",
  "iat" : 1455274182,
  "exp" : 1455274782,
  "act" : { "sub" : "admin" }  
}

Example claims set of an impersonated self-contained (JWT) access token:

{ 
  "iss" : "https://openid.c2id.com",
  "sub" : "claire",
  "aud" : "000123",
  "iat" : 1455274182,
  "exp" : 1455274782,
  "scp" : [ "openid", "profile", "email" ],
  "act" : { "sub" : "admin" }  
}

The actor JWT claim is defined according to the upcoming OAuth spec for token exchange. The claims's format permits the privileged user to come from a different domain (iss). It also permits impersonation / delegation chaining:

{ 
  "iss" : "https://openid.c2id.com",
  "sub" : "claire",
  "aud" : "000123",
  "iat" : 1455274182,
  "exp" : 1455274782,
  "act" : { "iss" : "https://openid.trusted.org", 
            "sub" : "admin",
            "act" : { "iss" : "https://openid.authority.org",
                      "sub" : "superuser" } }
}

For now only the simple case - same subject domain, no nesting -- is supported. But if you have a need to handle the more complex use cases, just drop us an email and we'll consider implementing that.

Direct impersonation / delegation

The special Connect2id endpoint for obtaining ID, access and refresh tokens directly, without going through the standard flows, has also been updated to support impersonation and delegation.

Example direct authorisation request with impersonation:

POST direct-authz/rest/v2 HTTP/1.1
Host: c2id.com
Authorization: Bearer ztucZS1ZyFKgh0tUEruUtiSTXhnexmd6
Content-Type: application/json

{
  "sub_session"      : { "sub" : "admin" },
  "client_id"        : "8cc2043",
  "scope"            : [ "openid", "email", "profile", "app:admin" ],
  "claims"           : [ "name", "email", "email_verified" ],
  "impersonated_sub" : "claire"
}

Querying, inspecting and revoking impersonations / delegations

Once an impersonated access or refresh token is issued, it can be inspected or revoked as any other token of the same type. The Connect2id server endpoint for these purposes was extended accordingly:

  • Querying long-lived (persisted) authorisations with the actor parameter.

  • Inspecting an authorisation code, access token or refresh token that is subject to impersonation / delegation, also done via the new actor parameter.

  • Revoking impersonated / delegation authorisations and tokens.

  • New RESTful resource for listing the actors that performed impersonation or delegation.

Example request to revoke all present tokens and authorisations for an impersonating / delegating actor with the user ID admin:

POST /authz-store/rest/v2/authorizations/revocation HTTP/1.1
Host: server.example.com
Authorization: Bearer ztucZS1ZyFKgh0tUEruUtiSTXhnexmd6
Content-Type: application/x-www-form-urlencoded

actor=admin

Adding arbitrary data to client registrations

We also closed a long standing ticket to enable the inclusion of arbitrary data with client registrations. Just set the custom "data" parameters, using a JSON object of your choice:

POST /c2id/clients HTTP/1.1
Host: demo.c2id.com
Content-Type: application/json
Authorization: Bearer ztucZS1ZyFKgh0tUEruUtiSTXhnexmd6

{
  "redirect_uris" : [ "https://myapp.example.com/callback" ],
  "data"          : { "reg_type"  : "3rd-party",
                      "approved"  : true,
                      "author_id" : 792440 }
}

The client data will then be automatically included in the consent prompt where you can use it as an input to your authorisation policy.

Note that registration of clients with data set requires extra privileges. Check out the updated client registration howto for more info.

Upgrading to 4.0.x

The new features in 4.x required changes to the underlying data structures, so the LDAP schema for the client registrations and the persisted authorisations must be updated on your servers.

Steps:

  1. Update the LDAP schemas to the latest 1.5 version. We've put together detailed instructions how to do that with OpenLDAP that requires no service downtime.

  2. Replace the /WEB-INF/oidcClientInfoMap.json configuration file which defines the mapping between JSON and LDAP attributes.

  3. Edit your existing /WEB-INF/authzStore.properties configuration:

    1. Make sure it contains the new authzStore.ldapDirectory.attributes.act property for representing actors in long-lived authorisations persisted to LDAP.
    2. Add act (actor) to the list of JWT claims to include in self-contained access tokens, unless your resource servers are not going to use this information. See the authzStore.accessToken.selfContainedClaims config docs for more info.

If you need help with upgrading, don't hesitate to get in touch with Connect2id support.

Download

To download a ZIP package of Connect2id server 4.0.1:

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

As WAR package only:

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

Note that the actual release version is 4.0.1, as we ended up including a fix for a bug that got discovered this morning just before the announcement.

Questions?

Please contact Connect2id support.


Release notes

4.0.1 (2016-02-12)

Configuration

  • /WEB-INF/oidcClientInfoMap.json

    • Corrects the entity mapping between the optional JSON object member "jwks" and the LDAP attribute "oauthJWKSet". See issue server/194 for more information.

Web API

  • No changes

Bug fixes

  • Fixes a bug that affected recreation of registered client JWK sets from persisted LDAP entries (issue server/194).

  • Prevent registration of custom client "data" parameters that are not a JSON object entity (issue server/195).

Dependencies

  • No changes

4.0 (2016-02-11)

Configuration

  • /WEB-INF/authzStore.properties

    • authzStore.accessToken.selfContainedClaims -- Adds support for an optional "act" (actor) JWT claim in issued self-contained access tokens. This claim can be used to indicate the authorised actor in impersonation (act-as) and delegation (on-behalf-of) cases. Its semantics is defined in draft-ietf-oauth-token-exchange-03, section 4.1.

    • authzStore.ldapDirectory.attributes.act -- New required configuration property to specify an LDAP attribute for representing impersonated and delegated authorisations. The LDAP attribute holds the identity of the impersonating or delegating subject (actor) and is intended to be used as part of the LDAP entry's RDN. Set to "authzActor".

  • /WEB-INF/oidcClientInfoMap.json

    • Adds a new entity mapping between the optional JSON object member "data" and the LDAP attribute "oauthClientData". See the client registration web API change log for more information.

Web API

  • /clients

    • Adds support for registering a custom "data" client metadata parameter, represented by a JSON object entity. Registration of this parameter requires the master registration token or an initial registration token with a "client-reg:data" scope.
  • /authz-sessions/rest/v2

    • Adds an optional "impersonated_sub" string parameter to the consent object representation. If set specifies a subject (end-user) to impersonate or delegate by means of the issued ID, access and refresh tokens. May be used to enable privileged users to login into clients and access protected resources under a different identity. The actual authorised subject (the impersonator) will be indicated in the custom "act" -> "sub" ID and access token (JWT) claim.

    • The optional "id_token" -> "impersonated_sub" parameter introduced in Connect2id server 3.x to enable limited ID token impersonation is deprecated in favour of the new top-level "impersonated_sub" parameter (see above).

    • Adds optional "impersonated_sub" string parameter to the authentication and consent prompt representations. If set indicates that the prompt is for a previously impersonated subject (end-user), as implied by an ID token hint submitted by the client. See the OpenID authentication request documentation for the "id_token_hint" parameter for more information.

  • /authz-store/rest/v2

    • Adds an "act" (actor) parameter to the authorisation representation to support impersonation (act-as) and delegation (on-behalf-of) cases.

    • Adds an /authz-store/rest/v2/actors resource for listing the indexed actors in long-lived (persisted) impersonated or delegated authorisations.

    • Adds support for an optional "actor" query parameter for GET requests to the /authz-store/rest/v2/authorizations resource. The "actor" query parameter can be used to retrieve impersonated and delegated authorisations using the actor as a key.

    • Adds support for an optional "actor" query parameter for POST requests to the /authz-store/rest/v2/revocation resource. The "actor" query parameter can be used to revoke impersonated and delegated authorisations using the actor as a key.

Bug fixes

  • Do not log authorisation codes, ID tokens, access tokens and refresh tokens unless at log level "TRACE" (security issue server/192).

  • Improves logging of failed client registration add, read, update and delete requests (issue server/163).

Dependencies

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

  • Upgrades to com.nimbusds:oauth2-oidc-sdk:5.5

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

  • Upgrades to com.nimbusds.nimbus-jose-jwt:4.12

  • Upgrades to com.nimbusds.common:1.99

Other

  • Upgrades the LDAP schema for client registrations to version 1.5:

    • Adds a new optional oauthClientData attribute for including additional client registration data formatted as a JSON object.
  • Upgrades the LDAP schema for persisted authorisations to version 1.5:

    • Adds a new optional authzActor attribute for representing impersonation and delegation cases.

Improved OAuth public client support and PKCE availability in Connect2id server 3.9

Improved public client support

The latest release of the Connect2id server for OpenID Connect and OAuth token based security has its focus on public clients. These are commonly used in situations where the client software is not hosted on a secure server, as is the case with traditional web apps, but instead resides on a user device (smartphone) or is executed inside a browser (for JavaScript based apps). In user environments client credentials cannot reliably be kept confidential, even if you resort to complicated techniques, such as encrypting the client secret inside the app code. Because even with such encryption, a dedicated hacker can still be a able to extract the secret while it's decrypted in the app memory.

With such clients you have two options:

  • Still provision the client with a client_id and client_secret, as with regular confidential clients, but don't assume that the secret is confidential, and can therefore be relied upon to verify the client.

  • Don't provision the client with a secret at all.

The latest release of the Connect2id server allows you to register public clients explicitly, by simply setting the token endpoint authentication method to none:

POST /c2id/clients HTTP/1.1
Host: demo.c2id.com
Authorization: Bearer ztucZS1ZyFKgh0tUEruUtiSTXhnexmd6
Content-Type: application/json

{
  "application_type"           : "native",
  "redirect_uris"              : [ "com.example.app:///auth" ],
  "token_endpoint_auth_method" : "none"
}

For a detailed explaination check out the public client registration how-to.

You can also check out the definition of public and confidential clients from the OAuth spec (RFC 6749) and the security considerations for client identification and authentication.

Authorising public clients

To aid consent for public clients, the authorisation session API was updated to indicate the type of the requesting client - whether it's confidential or public. This is done with help of the client.client_type parameter. Check out the consent prompt docs for more info.

Example consent prompt with the new client_type parameter:

HTTP/1.1 200 OK
Content-Type: application/json

{
  "type"        : "consent",
  "sid"         : "g6f5K6Kf6EY11zC00errCf64yLtg9lLANAcnXQk2xUE",
  "display"     : "popup",
  "sub_session" : { "sid"           : "9yLXidrzk91r3BCpJeF1Vrf_aza4oNe-EdNkaXBa1iw",
                    "sub"           : "alice",
                    "auth_time"     : 12345678,
                    "creation_time" : 12345678,
                    "max_life"      : 20160,
                    "auth_life"     : 1440,
                    "max_idle"      : 15 },
  "client"      : { "client_id"        : "8cc2043",
                    "client_type"      : "public",
                    "application_type" : "native" 
                    "name"             : "My Example App" },
  "scope"       : { "new"       : [ "openid", "email" ],
                    "consented" : [ ] },
  "claims"      : { "new"       : { "essential" : [ "email", "email_verified" ],
                                    "voluntary" : [ ] },
                    "consented" : { "essential" : [ ],
                                    "voluntary" : [ ] } }
}

Note that tokens issued to public clients should not be granted sensitive scopes, and their lifetime should be limited. Refresh tokens should not be issued unless required. The authorisation session API allows you to override the global token settings on a individual basis. So you can easily apply a public client policy when a "public" client.client_type parameter is detected.

Also, keep in mind that incremental authorisation is not feasible for a public client which client_id is shared across multiple app instances (e.g. for an app that is downloaded from an app store).

If you need to be able to distinguish between app instances for the purpose of authorisation (or other needs), and it doesn't matter whether the client is confidential or public, consider dynamic registration, that is registering each app instance with the Connect2id server once it's activated so it can obtain its own client_id. Self-registration can be managed via a proxy in front of the client registration endpoint and / or by use of a software statement - a JWT signed by the software publisher that locks down the parameters for the client registration.

If you need help with that get in touch with Connect2id support.

Proof key for code exchange (PKCE)

Public OAuth clients that use the code grant and run on smartphones are susceptible to a code interception attack. Fortunately, this attack can be successfully prevented by establishing a secure binding between the authorisation request and the subsequent token request.

The OAuth work group devised an official mini extension of the protocol for that, called Proof Key for Code Exchange (PKCE) and published in September 2015 as RFC 7636.

How does PKCE work?

  • The client creates a large random string called the code verifier.

  • The client then computes its SHA-256 hash, called the code_challenge.

  • The client passes the code_challenge and code_challenge_method (a keyword for the SHA-256 hash) along with the regular authorisation request parameters to the Connect2id server. The server stores them until a token request is received by the client.

  • When the client receives the authorisation code, it makes a token request with the code_verifier included. The Connect2id server recomputes the code challenge, and if it matches the original one, releases the requested tokens.

PKCE essentially works by preventing a malicious app or code had intercepted the code (as it was passed from the system browser / the OS to the app) from exchanging it for a token.

The latest release of the Connect2id server adds complete support for PKCE. In order to make use of it a public client just needs to set the appropriate PKCE request parameters. The server will take care of the rest.

If you're using the Connect2id OAuth / OpenID Connect SDK for Java (v 5.4+) PKCE is easy:

import com.nimbusds.oauth2.sdk.*;
import com.nimbusds.oauth2.sdk.id.*;
import com.nimbusds.oauth2.sdk.http.*;
import com.nimbusds.oauth2.sdk.pkce.
import com.nimbusds.oauth2.sdk.token.*;
import com.nimbusds.openid.connect.sdk.*;

// Generate random code verifier
CodeVerifier codeVerifier = new CodeVerifier();

// Compute code challenge using SHA-256
CodeChallenge codeChallenge = CodeChallenge.compute(CodeChallengeMethod.S256, codeVerifier);

// Make OpenID request and include code challenge + method
URI authRequestURI = new AuthenticationRequest.Builder(
            new ResponseType("code"), Scope.parse("openid email"), clientID, redirectURI,
            .state(new State())
            .codeChallenge(codeChallenge, CodeChallengeMethod.S256)
            .endpointURI("https://demo.c2id.com/login")
            .build()
            .toURI();

// Continue as usual...

// Make token request, include code verifier
AuthorizationGrant grant = new AuthorizationCodeGrant( code, redirectURI, codeVerifier);
TokenRequest tokenRequest = new TokenRequest(URI.create("https://demo.c2id.com/token", clientID, grant);
HTTPResponse httpResponse = tokenRequest.toHTTPRequest().send();

To obtain the tokens the client needs to supply the correct code verifier. Malicious third-party software that has intercepted the callback would not be able to do that, and the code will be withheld with the following error message:

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

{
  "error"             : "invalid_grant",
  "error_description" : "Invalid or expired authorization code, redirection URI mismatch, or PKCE verification failure"
}

Check out the superb JavaDocs if you need help with the SDK use.

Download

To download a ZIP package of Connect2id server 3.9:

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

As WAR package only:

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

Questions?

Please contact Connect2id support.


Connect2id Server 3.9 release notes

Configuration

  • /WEB-INF/oidcProvider.properties

    • Adds 'none' to the list of supported client authentication methods at the token endpoint (op.token.authMethods).

Web API

  • /clients

    • Enables explicit registration of public OAuth clients by setting the token_endpoint_auth_method parameter to 'none'.
  • /token

    • Adds support for Proof Key for Code Exchange (PKCE) to prevent authorisation code interception attacks on public OAuth clients.
  • /token/revoke

    • Public clients are permitted to revoke access and refresh tokens that have been issued to them.
  • /authz-sessions/rest/v2

    • Adds a "client_type" field with values "confidential" and "public" to the "client" object of authentication and consent prompts to indicate the OAuth client type.

Bug fixes

  • Permits client registration of custom URI schemas in addition to "http://localhost" for native applications (for application_type=native) (issue server/187).

  • Fixes unnecessary provisioning of client_secret for clients that are registered for the implicit grant only (with response types "id_token" or "token id_token" (issue server/184).

Dependencies

  • Upgrades to com.nimbusds:oauth2-oidc-sdk:5.4

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

  • Upgrades to org.bouncycastle:bcprov-jdk15on:1.54

Other

  • Improves the description of client registration invalid_redirect_uri error messages.

  • Changes the Connect2id server policy for logging the overriding system properties (if any) so that only the key names are written. This is done to prevent leaking of sensitive data into the server logs (issues authz-store/110 and server/186).