diff --git a/.changeset/cold-comics-rush.md b/.changeset/cold-comics-rush.md index edb481fd83..4bd9a4de22 100644 --- a/.changeset/cold-comics-rush.md +++ b/.changeset/cold-comics-rush.md @@ -4,3 +4,5 @@ --- Limited user tokens will no longer include the `ent` field in its payload. Ownership claims will now be fetched from the user info service. + +NOTE: Limited tokens issued prior to this change will no longer be valid. Users may have to clear their browser cookies in order to refresh their auth tokens. diff --git a/packages/backend-app-api/package.json b/packages/backend-app-api/package.json index f188b4aa51..9ede813a3a 100644 --- a/packages/backend-app-api/package.json +++ b/packages/backend-app-api/package.json @@ -79,6 +79,7 @@ "minimatch": "^9.0.0", "minimist": "^1.2.5", "morgan": "^1.10.0", + "node-fetch": "^2.6.7", "node-forge": "^1.3.1", "path-to-regexp": "^6.2.1", "selfsigned": "^2.0.0", diff --git a/packages/backend-app-api/src/services/implementations/userInfo/userInfoServiceFactory.ts b/packages/backend-app-api/src/services/implementations/userInfo/userInfoServiceFactory.ts index 5362ff83b0..db550bf9e8 100644 --- a/packages/backend-app-api/src/services/implementations/userInfo/userInfoServiceFactory.ts +++ b/packages/backend-app-api/src/services/implementations/userInfo/userInfoServiceFactory.ts @@ -24,6 +24,7 @@ import { } from '@backstage/backend-plugin-api'; import { ResponseError } from '@backstage/errors'; import { decodeJwt } from 'jose'; +import fetch from 'node-fetch'; import { toInternalBackstageCredentials } from '../auth/helpers'; type Options = { diff --git a/plugins/auth-backend/src/identity/TokenFactory.test.ts b/plugins/auth-backend/src/identity/TokenFactory.test.ts index d4221ed389..34e04aa858 100644 --- a/plugins/auth-backend/src/identity/TokenFactory.test.ts +++ b/plugins/auth-backend/src/identity/TokenFactory.test.ts @@ -22,6 +22,7 @@ import { decodeProtectedHeader, jwtVerify, } from 'jose'; +import { omit } from 'lodash'; import { MemoryKeyStore } from './MemoryKeyStore'; import { TokenFactory } from './TokenFactory'; import { UserInfoDatabaseHandler } from './UserInfoDatabaseHandler'; @@ -88,7 +89,7 @@ describe('TokenFactory', () => { ); expect(mockUserInfoDatabaseHandler.addUserInfo).toHaveBeenCalledWith({ - claims: verifyResult.payload, + claims: omit(verifyResult.payload, ['aud', 'iat', 'iss', 'uip']), }); // Emulate the reconstruction of a limited user token diff --git a/plugins/auth-backend/src/identity/TokenFactory.ts b/plugins/auth-backend/src/identity/TokenFactory.ts index 12798a4d79..a1643cdbe3 100644 --- a/plugins/auth-backend/src/identity/TokenFactory.ts +++ b/plugins/auth-backend/src/identity/TokenFactory.ts @@ -25,6 +25,7 @@ import { GeneralSign, KeyLike, } from 'jose'; +import { omit } from 'lodash'; import { DateTime } from 'luxon'; import { v4 as uuid } from 'uuid'; import { LoggerService } from '@backstage/backend-plugin-api'; @@ -220,7 +221,9 @@ export class TokenFactory implements TokenIssuer { // Store the user info in the database upon successful token // issuance so that it can be retrieved later by limited user tokens - await this.userInfoDatabaseHandler.addUserInfo({ claims }); + await this.userInfoDatabaseHandler.addUserInfo({ + claims: omit(claims, ['aud', 'iat', 'iss', 'uip']), + }); return token; } diff --git a/plugins/auth-backend/src/identity/UserInfoDatabaseHandler.test.ts b/plugins/auth-backend/src/identity/UserInfoDatabaseHandler.test.ts index b9f4d84bd5..ef3d0f6c8b 100644 --- a/plugins/auth-backend/src/identity/UserInfoDatabaseHandler.test.ts +++ b/plugins/auth-backend/src/identity/UserInfoDatabaseHandler.test.ts @@ -24,6 +24,8 @@ const migrationsDir = resolvePackagePath( 'migrations', ); +jest.setTimeout(60_000); + describe('UserInfoDatabaseHandler', () => { const databases = TestDatabases.create(); @@ -41,14 +43,14 @@ describe('UserInfoDatabaseHandler', () => { } describe.each(databases.eachSupportedId())( - '%p', + 'should support database %p', databaseId => { let knex: Knex; let dbHandler: UserInfoDatabaseHandler; beforeEach(async () => { ({ knex, dbHandler } = await createDatabaseHandler(databaseId)); - }, 30000); + }); it('addUserInfo', async () => { const userInfo = { @@ -104,6 +106,5 @@ describe('UserInfoDatabaseHandler', () => { expect(savedUserInfo).toEqual(userInfo); }); }, - 60000, ); }); diff --git a/yarn.lock b/yarn.lock index 977e2b724f..5fb392ee4d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3325,6 +3325,7 @@ __metadata: minimist: ^1.2.5 morgan: ^1.10.0 msw: ^1.0.0 + node-fetch: ^2.6.7 node-forge: ^1.3.1 path-to-regexp: ^6.2.1 selfsigned: ^2.0.0