Merge pull request #4635 from bleathem/oidc-scope

fixed: Expose a configuration option for the oidc scope
This commit is contained in:
Fredrik Adelöw
2021-02-23 22:08:37 +01:00
committed by GitHub
3 changed files with 39 additions and 32 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-auth-backend': patch
---
Expose a configuration option for the oidc scope
@@ -21,7 +21,7 @@ import { ClientMetadata, IssuerMetadata } from 'openid-client';
import { createOidcProvider, OidcAuthProvider } from './provider';
import { JWT, JWK } from 'jose';
import { AuthProviderFactoryOptions } from '../types';
import { Config } from '@backstage/config';
import { Config, ConfigReader } from '@backstage/config';
import { OAuthAdapter } from '../../lib/oauth';
const issuerMetadata = {
@@ -103,23 +103,18 @@ describe('OidcAuthProvider', () => {
const scope = nock('https://oidc.test')
.get('/.well-known/openid-configuration')
.reply(200, issuerMetadata);
const config: Config = new ConfigReader({
testEnv: {
...clientMetadata,
metadataUrl: 'https://oidc.test/.well-known/openid-configuration',
},
});
const options = {
globalConfig: {
appUrl: 'https://oidc.test',
baseUrl: 'https://oidc.test',
},
config: ({
keys: jest.fn(() => ['test']),
getConfig: jest.fn(() => ({
getString: (key: string) => {
const conf = {
...clientMetadata,
metadataUrl: 'https://oidc.test/.well-known/openid-configuration',
} as any;
return conf[key] as string;
},
})),
} as any) as Config,
config,
} as AuthProviderFactoryOptions;
const provider = createOidcProvider()(options) as OAuthAdapter;
expect(provider.start).toBeDefined();
@@ -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<OidcImpl>;
private readonly scope?: string;
constructor(options: Options) {
this.implementation = this.setupStrategy(options);
this.scope = options.scope;
}
async start(req: OAuthStartRequest): Promise<RedirectInfo> {
@@ -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<AuthResult, PrivateInfo>(
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, {