mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
fix: Add necessary claims to access and id tokens
This commit is contained in:
parent
e43b579ae7
commit
2be360a7af
@ -2,7 +2,10 @@
|
|||||||
"@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^1.0.0/components/context.jsonld",
|
"@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^1.0.0/components/context.jsonld",
|
||||||
"@graph": [
|
"@graph": [
|
||||||
{
|
{
|
||||||
"comment": "Sets all the relevant oidc parameters.",
|
"comment": [
|
||||||
|
"Sets all the relevant oidc parameters.",
|
||||||
|
"webid claim is in openid scope until an official scope has been decided: https://github.com/solid/authentication-panel/issues/86"
|
||||||
|
],
|
||||||
"@id": "urn:solid-server:default:IdentityProviderFactory",
|
"@id": "urn:solid-server:default:IdentityProviderFactory",
|
||||||
"@type": "IdentityProviderFactory",
|
"@type": "IdentityProviderFactory",
|
||||||
"args_adapterFactory": { "@id": "urn:solid-server:default:IdpAdapterFactory" },
|
"args_adapterFactory": { "@id": "urn:solid-server:default:IdpAdapterFactory" },
|
||||||
@ -13,7 +16,7 @@
|
|||||||
"args_responseWriter": { "@id": "urn:solid-server:default:ResponseWriter" },
|
"args_responseWriter": { "@id": "urn:solid-server:default:ResponseWriter" },
|
||||||
"config": {
|
"config": {
|
||||||
"claims": {
|
"claims": {
|
||||||
"webid": [ "webid", "client_id" ]
|
"openid": [ "webid", "client_id" ]
|
||||||
},
|
},
|
||||||
"cookies": {
|
"cookies": {
|
||||||
"long": { "signed": true, "maxAge": 86400000 },
|
"long": { "signed": true, "maxAge": 86400000 },
|
||||||
@ -33,6 +36,7 @@
|
|||||||
"formats": {
|
"formats": {
|
||||||
"AccessToken": "jwt"
|
"AccessToken": "jwt"
|
||||||
},
|
},
|
||||||
|
"scopes": [ "openid", "profile", "offline_access" ],
|
||||||
"ttl": {
|
"ttl": {
|
||||||
"AccessToken": 3600,
|
"AccessToken": 3600,
|
||||||
"AuthorizationCode": 600,
|
"AuthorizationCode": 600,
|
||||||
|
@ -120,10 +120,6 @@ export class IdentityProviderFactory implements ProviderFactory {
|
|||||||
return factory.createStorageAdapter(name);
|
return factory.createStorageAdapter(name);
|
||||||
};
|
};
|
||||||
|
|
||||||
// This needs to be a function, can't have a static string
|
|
||||||
// Sets the "aud" value to "solid" for all tokens
|
|
||||||
config.audiences = (): string => 'solid';
|
|
||||||
|
|
||||||
// Cast necessary due to typing conflict between jose 2.x and 3.x
|
// Cast necessary due to typing conflict between jose 2.x and 3.x
|
||||||
config.jwks = await this.generateJwks() as any;
|
config.jwks = await this.generateJwks() as any;
|
||||||
config.cookies = {
|
config.cookies = {
|
||||||
@ -175,22 +171,36 @@ export class IdentityProviderFactory implements ProviderFactory {
|
|||||||
return newCookieSecret;
|
return newCookieSecret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the given token is an access token.
|
||||||
|
* The AccessToken interface is not exported so we have to access it like this.
|
||||||
|
*/
|
||||||
|
private isAccessToken(token: any): token is KoaContextWithOIDC['oidc']['accessToken'] {
|
||||||
|
return token.kind === 'AccessToken';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds the necessary claims the to id token and access token based on the Solid OIDC spec.
|
* Adds the necessary claims the to id token and access token based on the Solid OIDC spec.
|
||||||
*/
|
*/
|
||||||
private configureClaims(config: Configuration): void {
|
private configureClaims(config: Configuration): void {
|
||||||
// Returns the id_token and adds the webid claim
|
// Access token audience is 'solid', ID token audience is the client_id
|
||||||
|
config.audiences = (ctx, sub, token, use): string =>
|
||||||
|
use === 'access_token' ? 'solid' : token.clientId!;
|
||||||
|
|
||||||
|
// Returns the id_token
|
||||||
|
// See https://solid.github.io/authentication-panel/solid-oidc/#tokens-id
|
||||||
config.findAccount = async(ctx: KoaContextWithOIDC, sub: string): Promise<Account> => ({
|
config.findAccount = async(ctx: KoaContextWithOIDC, sub: string): Promise<Account> => ({
|
||||||
accountId: sub,
|
accountId: sub,
|
||||||
claims: async(): Promise<{ sub: string; [key: string]: any }> => ({ sub, webid: sub }),
|
claims: async(): Promise<{ sub: string; [key: string]: any }> =>
|
||||||
|
({ sub, webid: sub }),
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add extra claims in case an AccessToken is being issued.
|
// Add extra claims in case an AccessToken is being issued.
|
||||||
// Specifically this sets the required webid and client_id claims for the access token
|
// Specifically this sets the required webid and client_id claims for the access token
|
||||||
|
// See https://solid.github.io/authentication-panel/solid-oidc/#tokens-access
|
||||||
config.extraAccessTokenClaims = (ctx, token): CanBePromise<AnyObject | void> =>
|
config.extraAccessTokenClaims = (ctx, token): CanBePromise<AnyObject | void> =>
|
||||||
// AccessToken interface is not exported
|
this.isAccessToken(token) ?
|
||||||
(token as any).accountId ?
|
{ webid: token.accountId, client_id: token.clientId } :
|
||||||
{ webid: (token as any).accountId, client_id: 'http://localhost:3001/' } :
|
|
||||||
{};
|
{};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,17 +94,18 @@ describe('An IdentityProviderFactory', (): void => {
|
|||||||
expect(config.routes).toEqual(routes);
|
expect(config.routes).toEqual(routes);
|
||||||
|
|
||||||
expect((config.interactions?.url as any)()).toEqual('/idp/');
|
expect((config.interactions?.url as any)()).toEqual('/idp/');
|
||||||
expect((config.audiences as any)()).toBe('solid');
|
expect((config.audiences as any)(null, null, {}, 'access_token')).toBe('solid');
|
||||||
|
expect((config.audiences as any)(null, null, { clientId: 'clientId' }, 'client_credentials')).toBe('clientId');
|
||||||
|
|
||||||
const findResult = await config.findAccount?.({} as any, webId);
|
const findResult = await config.findAccount?.({ oidc: { client: { clientId: 'clientId' }}} as any, webId);
|
||||||
expect(findResult?.accountId).toBe(webId);
|
expect(findResult?.accountId).toBe(webId);
|
||||||
await expect((findResult?.claims as any)()).resolves.toEqual({ sub: webId, webid: webId });
|
await expect((findResult?.claims as any)()).resolves.toEqual({ sub: webId, webid: webId });
|
||||||
|
|
||||||
expect((config.extraAccessTokenClaims as any)({}, {})).toEqual({});
|
expect((config.extraAccessTokenClaims as any)({}, {})).toEqual({});
|
||||||
expect((config.extraAccessTokenClaims as any)({}, { accountId: webId })).toEqual({
|
expect((config.extraAccessTokenClaims as any)({}, { kind: 'AccessToken', accountId: webId, clientId: 'clientId' }))
|
||||||
|
.toEqual({
|
||||||
webid: webId,
|
webid: webId,
|
||||||
// This will need to change once #718 is fixed
|
client_id: 'clientId',
|
||||||
client_id: 'http://localhost:3001/',
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Test the renderError function
|
// Test the renderError function
|
||||||
|
Loading…
x
Reference in New Issue
Block a user