Custom token response
1. Overview
The OAuth 2.0 framework (RFC 6749) allows for additional parameters to be sent in the access token response. This is used for instance by OpenID Connect to return its ID token to the relying party and by the new Rich Authorisation Requests (RAR) to include metadata about the token’s capabilities.
Example access token response which includes RAR metadata:
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-cache, no-store
Pragma: no-cache
{
"access_token": "2YotnFZFEjr1zCsicMWpAA",
"token_type": "example",
"expires_in": 3600,
"refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA",
"authorization_details": [
{
"type": "https://www.someorg.com/payment_initiation",
"actions": [
"initiate",
"status",
"cancel"
],
"locations": [
"https://example.com/payments"
],
"instructedAmount": {
"currency": "EUR",
"amount": "123.50"
},
"creditorName": "Merchant123",
"creditorAccount": {
"iban": "DE02100100109307118603"
},
"remittanceInformationUnstructured": "Ref Number Merchant"
}
]
}
If a Connect2id server deployment needs to return additional parameters in the token response it can do so by creating an SPI plugin.
2. Custom token response composer SPI
The creation of custom token success and error responses is facilitated via the CustomTokenResponseComposer (SPI) from the Connect2id server SDK.
Implementations have access to
-
The original token success or error response.
-
The Connect2id server issuer URI.
-
The registered information for the client (if successfully authenticated or identified).
-
The authorisation
data
parameter, set during consent. -
The OpenID claim source.
If there is no need to modify the token response the plugin can simply pass it through.
If the Connect2id server detects an SPI implementation it will log its loading
under OP6218
.
INFO main MAIN - [OP6218] Loaded custom token response composer: class=com.nimbusds.openid.connect.provider.spi.tokens.response.impl.RARCustomizer enabled=true
3. Sample RAR plugin
This is a sample RAR plugin that obtains the content of the
authorization_details
from the optional authorisation data set during
consent.
Token error responses and responses which have no associated RAR details are simply returned unmodified.
import net.minidev.json.JSONObject;
import com.nimbusds.oauth2.sdk.*;
import com.nimbusds.oauth2.sdk.util.*;
import com.nimbusds.openid.connect.provider.spi.tokens.response.*;
public class RARCustomizer implements CustomTokenResponseComposer {
@Override
public TokenResponse compose(final TokenResponse originalResponse,
final TokenResponseContext context) {
if (originalResponse instanceof TokenErrorResponse) {
return originalResponse;
}
JSONObject authzData = context.getAuthorizationData();
if (authzData == null) {
// No data / RAR
return originalResponse;
}
JSONObject rarDetails;
try {
rarDetails = JSONObjectUtils.getJSONObject(
authzData,
"authorization_details",
null);
} catch (ParseException e) {
throw new RuntimeException("Internal error: " + e.getMessage(), e);
}
if (rarDetails == null) {
// No RAR
return originalResponse;
}
AccessTokenResponse successResponse = originalResponse.toSuccessResponse();
try {
JSONObject tokensObject = successResponse.toJSONObject();
tokensObject.put("authorization_details", rarDetails);
return AccessTokenResponse.parse(tokensObject);
} catch (ParseException e) {
throw new RuntimeException("Internal error: " + e.getMessage(), e);
}
}
}