mirror of
https://github.com/logto-io/logto.git
synced 2025-01-27 21:39:16 -05:00
feat(core): handle oidc scopes for token exchange (#6147)
* feat(core,schemas): token exchange grant * feat(core): third-party applications are not allowed for token exchange * feat(core,schemas): token exchange grant * feat(core): organization token for token exchange flow * feat(core): handle oidc scopes for token exchange
This commit is contained in:
parent
de9ee8962a
commit
504f5b2a99
2 changed files with 32 additions and 3 deletions
|
@ -73,6 +73,7 @@ export const buildHandler: (
|
|||
const providerInstance = instance(provider);
|
||||
const {
|
||||
features: { userinfo, resourceIndicators },
|
||||
scopes: oidcScopes,
|
||||
} = providerInstance.configuration();
|
||||
|
||||
const subjectToken = await trySafe(async () => findSubjectToken(String(params.subject_token)));
|
||||
|
@ -186,9 +187,15 @@ export const buildHandler: (
|
|||
.filter(Set.prototype.has.bind(accessToken.resourceServer.scopes))
|
||||
.join(' ');
|
||||
} else {
|
||||
// TODO: (LOG-9166) Check claims and scopes
|
||||
accessToken.claims = ctx.oidc.claims;
|
||||
accessToken.scope = Array.from(scope).join(' ');
|
||||
// Filter scopes from `oidcScopes`,
|
||||
// in other grants, this is done by `Grant` class
|
||||
// See https://github.com/panva/node-oidc-provider/blob/0c569cf5c36dd5faa105fb931a43b2e587530def/lib/helpers/oidc_context.js#L159
|
||||
accessToken.scope = Array.from(scope)
|
||||
// Wrong typing for oidc-provider, `oidcScopes` is actully a Set,
|
||||
// wrap it with `new Set` to make it work
|
||||
.filter((name) => new Set(oidcScopes).has(name))
|
||||
.join(' ');
|
||||
}
|
||||
/* eslint-enable @silverhand/fp/no-mutation, @typescript-eslint/no-unsafe-assignment */
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { buildOrganizationUrn } from '@logto/core-kit';
|
||||
import { UserScope, buildOrganizationUrn } from '@logto/core-kit';
|
||||
import { decodeAccessToken } from '@logto/js';
|
||||
import { ApplicationType, GrantType, MfaFactor } from '@logto/schemas';
|
||||
import { formUrlEncodedHeaders } from '@logto/shared';
|
||||
|
@ -137,6 +137,28 @@ describe('Token Exchange', () => {
|
|||
|
||||
await deleteApplication(thirdPartyApplication.id);
|
||||
});
|
||||
|
||||
it('should filter out non-oidc scopes', async () => {
|
||||
const { subjectToken } = await createSubjectToken(userId);
|
||||
|
||||
const body = await oidcApi
|
||||
.post('token', {
|
||||
headers: formUrlEncodedHeaders,
|
||||
body: new URLSearchParams({
|
||||
client_id: applicationId,
|
||||
grant_type: GrantType.TokenExchange,
|
||||
subject_token: subjectToken,
|
||||
subject_token_type: 'urn:ietf:params:oauth:token-type:access_token',
|
||||
scope: [UserScope.Profile, 'non-oidc-scope'].join(' '),
|
||||
}),
|
||||
})
|
||||
.json();
|
||||
|
||||
expect(body).toHaveProperty('access_token');
|
||||
expect(body).toHaveProperty('token_type', 'Bearer');
|
||||
expect(body).toHaveProperty('expires_in');
|
||||
expect(body).toHaveProperty('scope', UserScope.Profile);
|
||||
});
|
||||
});
|
||||
|
||||
describe('get access token for organization', () => {
|
||||
|
|
Loading…
Add table
Reference in a new issue