diff --git a/.changeset/sweet-experts-whisper.md b/.changeset/sweet-experts-whisper.md new file mode 100644 index 0000000000..ca2f89ceb7 --- /dev/null +++ b/.changeset/sweet-experts-whisper.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-backend': patch +--- + +Expose a configuration option for the oidc scope diff --git a/plugins/auth-backend/src/providers/oidc/provider.ts b/plugins/auth-backend/src/providers/oidc/provider.ts index 0ec8d0bbf7..c7df8c1e7e 100644 --- a/plugins/auth-backend/src/providers/oidc/provider.ts +++ b/plugins/auth-backend/src/providers/oidc/provider.ts @@ -55,14 +55,17 @@ type AuthResult = { export type Options = OAuthProviderOptions & { metadataUrl: string; + scope?: string; tokenSignedResponseAlg?: string; }; export class OidcAuthProvider implements OAuthHandlers { private readonly implementation: Promise; + private readonly scope?: string; constructor(options: Options) { this.implementation = this.setupStrategy(options); + this.scope = options.scope; } async start(req: OAuthStartRequest): Promise { @@ -70,7 +73,7 @@ export class OidcAuthProvider implements OAuthHandlers { return await executeRedirectStrategy(req, strategy, { accessType: 'offline', prompt: 'none', - scope: req.scope, + scope: req.scope || this.scope || '', state: encodeState(req.state), }); } @@ -79,28 +82,29 @@ export class OidcAuthProvider implements OAuthHandlers { req: express.Request, ): Promise<{ response: OAuthResponse; refreshToken?: string }> { const { strategy } = await this.implementation; + const strategyResponse = await executeFrameHandlerStrategy< + AuthResult, + PrivateInfo + >(req, strategy); const { result: { userinfo, tokenset }, privateInfo, - } = await executeFrameHandlerStrategy( - req, - strategy, - ); - + } = strategyResponse; + const identityResponse = await this.populateIdentity({ + profile: { + displayName: userinfo.name, + email: userinfo.email, + picture: userinfo.picture, + }, + providerInfo: { + idToken: tokenset.id_token, + accessToken: tokenset.access_token || '', + scope: tokenset.scope || '', + expiresInSeconds: tokenset.expires_in, + }, + }); return { - response: await this.populateIdentity({ - profile: { - displayName: userinfo.name, - email: userinfo.email, - picture: userinfo.picture, - }, - providerInfo: { - idToken: tokenset.id_token, - accessToken: tokenset.access_token || '', - scope: tokenset.scope || '', - expiresInSeconds: tokenset.expires_in, - }, - }), + response: identityResponse, refreshToken: privateInfo.refreshToken, }; } @@ -133,6 +137,7 @@ export class OidcAuthProvider implements OAuthHandlers { redirect_uris: [options.callbackUrl], response_types: ['code'], id_token_signed_response_alg: options.tokenSignedResponseAlg || 'RS256', + scope: options.scope || '', }); const strategy = new OidcStrategy( @@ -188,6 +193,7 @@ export const createOidcProvider = ( const tokenSignedResponseAlg = envConfig.getString( 'tokenSignedResponseAlg', ); + const scope = envConfig.getOptionalString('scope'); const provider = new OidcAuthProvider({ clientId, @@ -195,6 +201,7 @@ export const createOidcProvider = ( callbackUrl, tokenSignedResponseAlg, metadataUrl, + scope, }); return OAuthAdapter.fromConfig(globalConfig, provider, {