Skip to content

Commit 0fc5893

Browse files
committed
feat: add RAR support to CIBA flows
resolves #1358
1 parent 91052ca commit 0fc5893

File tree

7 files changed

+63
-10
lines changed

7 files changed

+63
-10
lines changed

docs/README.md

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2051,6 +2051,7 @@ _**default value**_:
20512051
ack: undefined,
20522052
enabled: false,
20532053
rarForAuthorizationCode: [Function: rarForAuthorizationCode], // see expanded details below
2054+
rarForBackchannelResponse: [Function: rarForBackchannelResponse], // see expanded details below
20542055
rarForCodeResponse: [Function: rarForCodeResponse], // see expanded details below
20552056
rarForIntrospectionResponse: [Function: rarForIntrospectionResponse], // see expanded details below
20562057
rarForRefreshTokenResponse: [Function: rarForRefreshTokenResponse], // see expanded details below
@@ -2080,9 +2081,30 @@ rarForAuthorizationCode(ctx) {
20802081
}
20812082
```
20822083
2084+
#### rarForBackchannelResponse
2085+
2086+
Specifies a helper function that shall be invoked to transform the requested and granted Rich Authorization Request details for inclusion in the Access Token Response as authorization_details and assignment to the issued Access Token during the ciba grant. This function enables resource-specific filtering and transformation of authorization details according to token endpoint policy. The function shall return an array of authorization details or undefined.
2087+
2088+
2089+
_**default value**_:
2090+
```js
2091+
rarForBackchannelResponse(ctx, resourceServer) {
2092+
// decision points:
2093+
// - ctx.oidc.client
2094+
// - resourceServer
2095+
// - ctx.oidc.entities.BackchannelAuthenticationRequest.rar (the rar applied during await provider.backchannelResult())
2096+
// - ctx.oidc.entities.BackchannelAuthenticationRequest.params.authorization_details (the original backchannel authentication request authorization_details object)
2097+
// - ctx.oidc.params.authorization_details (unparsed authorization_details from the body params in the Access Token Request)
2098+
// - ctx.oidc.grant.rar (authorization_details granted)
2099+
throw new Error(
2100+
'features.richAuthorizationRequests.rarForBackchannelResponse not implemented',
2101+
);
2102+
}
2103+
```
2104+
20832105
#### rarForCodeResponse
20842106
2085-
Specifies a helper function that shall be invoked to transform the requested and granted Rich Authorization Request details for inclusion in the Access Token Response as authorization_details and assignment to the issued Access Token. This function enables resource-specific filtering and transformation of authorization details according to token endpoint policy. The function shall return an array of authorization details or undefined.
2107+
Specifies a helper function that shall be invoked to transform the requested and granted Rich Authorization Request details for inclusion in the Access Token Response as authorization_details and assignment to the issued Access Token during the authorization code grant. This function enables resource-specific filtering and transformation of authorization details according to token endpoint policy. The function shall return an array of authorization details or undefined.
20862108
20872109
20882110
_**default value**_:

lib/actions/authorization/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,8 @@ export default function authorizationAction(provider, endpoint) {
174174
use(() => checkRedirectUri, A, PAR );
175175
use(() => checkPKCE, A, PAR );
176176
use(() => checkClaims, A, DA, PAR, BA);
177-
use(() => unsupportedRar, DA, BA);
178-
use(() => checkRar, A, PAR );
177+
use(() => unsupportedRar, DA );
178+
use(() => checkRar, A, PAR, BA);
179179
use(() => checkResource, A, DA, R, CV, DR, PAR, BA);
180180
use(() => checkMaxAge, A, DA, PAR, BA);
181181
use(() => checkRequestedExpiry, BA);

lib/actions/grants/ciba.js

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import epochTime from '../../helpers/epoch_time.js';
1111
import getCtxAccountClaims from '../../helpers/account_claims.js';
1212
import { setRefreshTokenBindings } from '../../helpers/set_rt_bindings.js';
1313
import { checkAttestBinding } from '../../helpers/check_attest_binding.js';
14+
import checkRar from '../../shared/check_rar.js';
1415

1516
const {
1617
AuthorizationPending,
@@ -23,10 +24,6 @@ export const gty = 'ciba';
2324
export const handler = async function cibaHandler(ctx) {
2425
presence(ctx, 'auth_req_id');
2526

26-
if (ctx.oidc.params.authorization_details) {
27-
throw new errors.InvalidRequest('authorization_details is unsupported for this grant_type');
28-
}
29-
3027
const {
3128
findAccount,
3229
issueRefreshToken,
@@ -36,6 +33,7 @@ export const handler = async function cibaHandler(ctx) {
3633
mTLS: { getCertificate },
3734
dPoP: { allowReplay },
3835
resourceIndicators,
36+
richAuthorizationRequests,
3937
},
4038
} = instance(ctx.oidc.provider).configuration;
4139

@@ -156,6 +154,7 @@ export const handler = async function cibaHandler(ctx) {
156154
at.setThumbprint('jkt', dPoP.thumbprint);
157155
}
158156

157+
await checkRar(ctx, () => {});
159158
const resource = await resolveResource(ctx, request, { userinfo, resourceIndicators });
160159

161160
if (resource) {
@@ -168,6 +167,10 @@ export const handler = async function cibaHandler(ctx) {
168167
at.scope = grant.getOIDCScopeFiltered(request.scopes);
169168
}
170169

170+
if (richAuthorizationRequests.enabled && at.resourceServer) {
171+
at.rar = await richAuthorizationRequests.rarForBackchannelResponse(ctx, at.resourceServer);
172+
}
173+
171174
ctx.oidc.entity('AccessToken', at);
172175
const accessToken = await at.save();
173176

@@ -189,6 +192,7 @@ export const handler = async function cibaHandler(ctx) {
189192
scope: request.scope,
190193
sessionUid: request.sessionUid,
191194
sid: request.sid,
195+
rar: request.rar,
192196
});
193197

194198
await setRefreshTokenBindings(ctx, at, rt);
@@ -232,6 +236,7 @@ export const handler = async function cibaHandler(ctx) {
232236
refresh_token: refreshToken,
233237
scope: request.scope ? at.scope : (at.scope || undefined),
234238
token_type: at.tokenType,
239+
authorization_details: at.rar,
235240
};
236241
};
237242

lib/actions/grants/refresh_token.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,11 @@ import checkRar from '../../shared/check_rar.js';
1313
import getCtxAccountClaims from '../../helpers/account_claims.js';
1414
import { checkAttestBinding } from '../../helpers/check_attest_binding.js';
1515

16-
import { gty as cibaGty } from './ciba.js';
1716
import { gty as deviceCodeGty } from './device_code.js';
1817

1918
function rarSupported(token) {
2019
const [origin] = token.gty.split(' ');
21-
return origin !== cibaGty && origin !== deviceCodeGty;
20+
return origin !== deviceCodeGty;
2221
}
2322

2423
const gty = 'refresh_token';

lib/helpers/defaults.js

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1933,7 +1933,8 @@ function makeDefaults() {
19331933
*
19341934
* description: Specifies a helper function that shall be invoked to transform the requested
19351935
* and granted Rich Authorization Request details for inclusion in the Access Token Response
1936-
* as authorization_details and assignment to the issued Access Token. This function enables
1936+
* as authorization_details and assignment to the issued Access Token during the authorization code grant.
1937+
* This function enables
19371938
* resource-specific filtering and transformation of authorization details according to
19381939
* token endpoint policy. The function shall return an array of authorization details or undefined.
19391940
*/
@@ -1949,6 +1950,29 @@ function makeDefaults() {
19491950
'features.richAuthorizationRequests.rarForCodeResponse not implemented',
19501951
);
19511952
},
1953+
/*
1954+
* features.richAuthorizationRequests.rarForBackchannelResponse
1955+
*
1956+
* description: Specifies a helper function that shall be invoked to transform the requested
1957+
* and granted Rich Authorization Request details for inclusion in the Access Token Response
1958+
* as authorization_details and assignment to the issued Access Token during the ciba grant.
1959+
* This function enables
1960+
* resource-specific filtering and transformation of authorization details according to
1961+
* token endpoint policy. The function shall return an array of authorization details or undefined.
1962+
*/
1963+
rarForBackchannelResponse(ctx, resourceServer) {
1964+
// decision points:
1965+
// - ctx.oidc.client
1966+
// - resourceServer
1967+
// - ctx.oidc.entities.BackchannelAuthenticationRequest.rar (the rar applied during await provider.backchannelResult())
1968+
// - ctx.oidc.entities.BackchannelAuthenticationRequest.params.authorization_details (the original backchannel authentication request authorization_details object)
1969+
// - ctx.oidc.params.authorization_details (unparsed authorization_details from the body params in the Access Token Request)
1970+
// - ctx.oidc.grant.rar (authorization_details granted)
1971+
mustChange('features.richAuthorizationRequests.rarForBackchannelResponse', 'transform the requested and granted RAR details to be returned in the Access Token Response as authorization_details as well as assigned to the issued Access Token');
1972+
throw new Error(
1973+
'features.richAuthorizationRequests.rarForBackchannelResponse not implemented',
1974+
);
1975+
},
19521976
/*
19531977
* features.richAuthorizationRequests.rarForRefreshTokenResponse
19541978
*

lib/models/backchannel_authentication_request.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export default (provider) => class BackchannelAuthenticationRequest extends appl
2020
'error',
2121
'errorDescription',
2222
'params',
23+
'rar',
2324
];
2425
}
2526
};

lib/provider.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ export class Provider extends Koa {
237237
sessionUid,
238238
expiresWithSession,
239239
sid,
240+
rar,
240241
} = {}) {
241242
if (typeof request === 'string' && request) {
242243
// eslint-disable-next-line no-param-reassign
@@ -281,6 +282,7 @@ export class Provider extends Koa {
281282
sessionUid,
282283
expiresWithSession,
283284
sid,
285+
rar,
284286
});
285287
break;
286288
case result instanceof OIDCProviderError:

0 commit comments

Comments
 (0)