Rich Authorisation Requests (RAR)
Rich authorisation requests (RFC 9396) is an OAuth 2.0 extension for expressing the authorisation specific parameters of a request as a JSON object. It is intended as an alternative to the simple and widely used OAuth 2.0 scope parameter, which is a space separated string of keywords for an aspect of access to a protected resource.
The RAR JSON object objects must be typed and define several optional parameters for expressing an authorisation:
-
locations – The resources for which access is requested, typically a single valued array with the URL of the resource server. Resembles the
resource
parameter in RFC 8707. -
actions – The actions to be performed at the resource, typically expressed as verbs.
-
datatypes – The types of data requested from the resource.
-
identifier – To identify a specific resource.
-
privileges – The types or levels of access requested for the resource.
Example:
{
"type" : "message_api_v1",
"locations" : [ "https://api.example.com/messages" ],
"actions" : [ "post", "get", "search" ]
}
Authorisation request
Example Java code for a rich authorisation request recreating the above example:
import com.nimbusds.oauth2.sdk.*;
import com.nimbusds.oauth2.sdk.pkce.*;
import com.nimbusds.oauth2.sdk.rar.*;
import java.net.*;
import java.util.*;
// For PKCE
CodeVerifier codeVerifier = new CodeVerifier();
// Compose the authorisation detail
AuthorizationDetail authzDetail = new AuthorizationDetail.Builder(
new AuthorizationType("message_api_v1"))
.locations(
Collections.singletonList(
new Location(URI.create("https://api.example.com/messages"))))
.actions(
Arrays.asList(
new Action("read"),
new Action("get"),
new Action("search")))
.build();
// Compose the OAuth 2.0 authorisation request
AuthorizationRequest request = new AuthorizationRequest.Builder(
ResponseType.CODE,
new ClientID("123"))
.endpointURI(URI.create("https://demo.c2id.com/login"))
.authorizationDetails(Collections.singletonList(authzDetail))
.redirectionURI(URI.create("https://client.example.com/cb"))
.codeChallenge(codeVerifier, CodeChallengeMethod.S256)
.state(new State())
.build();
// Print the request
System.out.println(request.toURI());
Example output:
https://demo.c2id.com/login?
&response_type=code
&client_id=123
authorization_details=%5B%7B%22locations%22%3A%5B%22https%3A%5C%2F%5C%2Fapi.example.com%5C%2Fmessages%22%5D%2C%22type%22%3A%22message_api_v1%22%2C%22actions%22%3A%5B%22read%22%2C%22get%22%2C%22search%22%5D%7D%5D
&redirect_uri=https%3A%2F%2Fclient.example.com%2Fcb
&code_challenge_method=S256
&code_challenge=fu8tw3VznKQBN4HFGVta4k8Nj2S4ta10vRU-vLK3DhQ
&state=6YrLp40CZiCoDNlR49-6T9jv6d1KUKJDBBfRBGpiyRE
The RAR package
The classes to build and parse authorization_details
objects in a type-safe
manner are located in the
com.nimbusds.oauth2.sdk.rar
package.
Example recreation of the authorisation detail in figure 2 of the standard:
JSONObject instructedAmount = new JSONObject();
instructedAmount.put("currency", "EUR");
instructedAmount.put("amount", "123.50");
JSONObject creditorAccount = new JSONObject();
creditorAccount.put("iban", "DE02100100109307118603");
AuthorizationDetail detail = new AuthorizationDetail.Builder(
new AuthorizationType("payment_initiation"))
.actions(Arrays.asList(
new Action("initiate"),
new Action("status"),
new Action("cancel")))
.locations(Collections.singletonList(
new Location(URI.create("https://example.com/payments"))))
.field("instructedAmount", instructedAmount)
.field("creditorName", "Merchant A")
.field("creditorAccount", creditorAccount)
.field("remittanceInformationUnstructured", "Ref Number Merchant")
.build();
Token request with authorization_details
Here is an example token request
using the client credentials grant with an authorization_details
parameter:
// The client credentials
ClientID clientID = new ClientID("123");
Secret clientSecret = new Secret("moof9Lo7nohXeutoosh1uz8kiiZahngi");
// Compose the authorisation detail
AuthorizationDetail authzDetail = new AuthorizationDetail.Builder(
new AuthorizationType("message_api_v1"))
.locations(
Collections.singletonList(
new Location(URI.create("https://api.example.com/messages"))))
.actions(
Arrays.asList(
new Action("read"),
new Action("get"),
new Action("search")))
.build();
TokenRequest request = new TokenRequest(
URI.create("https://demo.c2id.com/token"),
new ClientSecretBasic(new ClientID("123"), new Secret()),
new ClientCredentialsGrant(new ClientID("123")),
null, // no scope
Collections.singletonList(authzDetail),
null, // no resources
null); // no custom params
// Make HTTP request
HTTPRequest httpRequest = request.toHTTPRequest();
HTTPResponse httpResponse = request.send();