diff --git a/plugins/auth-backend/src/lib/EnvironmentHandler.ts b/plugins/auth-backend/src/lib/EnvironmentHandler.ts
index 6c16b3a712..76c1f40b73 100644
--- a/plugins/auth-backend/src/lib/EnvironmentHandler.ts
+++ b/plugins/auth-backend/src/lib/EnvironmentHandler.ts
@@ -16,49 +16,56 @@
import express from 'express';
import { AuthProviderRouteHandlers } from '../providers/types';
-import { NotFoundError } from '@backstage/backend-common';
export type EnvironmentHandlers = {
[key: string]: AuthProviderRouteHandlers;
};
export class EnvironmentHandler implements AuthProviderRouteHandlers {
- constructor(private readonly providers: EnvironmentHandlers) {}
+ constructor(
+ private readonly providerId: string,
+ private readonly providers: EnvironmentHandlers,
+ ) {}
- private getProviderForEnv(req: express.Request): AuthProviderRouteHandlers {
+ private getProviderForEnv(
+ req: express.Request,
+ res: express.Response,
+ ): AuthProviderRouteHandlers | undefined {
const env = req.query.env?.toString();
- if (!this.providers.hasOwnProperty(env)) {
- throw new NotFoundError(
- `No environment for ${env} found in this provider`,
- );
+
+ if (this.providers.hasOwnProperty(env)) {
+ return this.providers[env];
}
- return this.providers[env];
+
+ res.status(404).send(
+ `Missing configuration.
+
+
+For this flow to work you need to supply a valid configuration for the "${env}" environment of the "${this.providerId}" provider.`,
+ );
+ return undefined;
}
async start(req: express.Request, res: express.Response): Promise {
- const provider = this.getProviderForEnv(req);
- await provider.start(req, res);
+ const provider = this.getProviderForEnv(req, res);
+ await provider?.start(req, res);
}
async frameHandler(
req: express.Request,
res: express.Response,
): Promise {
- const provider = this.getProviderForEnv(req);
- await provider.frameHandler(req, res);
+ const provider = this.getProviderForEnv(req, res);
+ await provider?.frameHandler(req, res);
}
async refresh(req: express.Request, res: express.Response): Promise {
- const provider = this.getProviderForEnv(req);
- if (provider.refresh) {
- await provider.refresh(req, res);
- }
+ const provider = this.getProviderForEnv(req, res);
+ await provider?.refresh?.(req, res);
}
async logout(req: express.Request, res: express.Response): Promise {
- const provider = this.getProviderForEnv(req);
- if (provider.logout) {
- await provider.logout(req, res);
- }
+ const provider = this.getProviderForEnv(req, res);
+ await provider?.logout?.(req, res);
}
}
diff --git a/plugins/auth-backend/src/providers/github/provider.ts b/plugins/auth-backend/src/providers/github/provider.ts
index ed06c5786e..bd7d4aa712 100644
--- a/plugins/auth-backend/src/providers/github/provider.ts
+++ b/plugins/auth-backend/src/providers/github/provider.ts
@@ -135,16 +135,16 @@ export function createGithubProvider(
logger: Logger,
tokenIssuer: TokenIssuer,
) {
+ const providerId = 'github';
const envProviders: EnvironmentHandlers = {};
for (const [env, envConfig] of Object.entries(providerConfig)) {
const config = (envConfig as unknown) as OAuthProviderConfig;
const { secure, appOrigin } = config;
- const callbackURLParam = `?env=${env}`;
const opts = {
clientID: config.clientId,
clientSecret: config.clientSecret,
- callbackURL: `${baseUrl}/github/handler/frame${callbackURLParam}`,
+ callbackURL: `${baseUrl}/${providerId}/handler/frame?env=${env}`,
};
if (!opts.clientID || !opts.clientSecret) {
@@ -163,12 +163,12 @@ export function createGithubProvider(
envProviders[env] = new OAuthProvider(new GithubAuthProvider(opts), {
disableRefresh: true,
persistScopes: true,
- providerId: 'github',
+ providerId,
secure,
baseUrl,
appOrigin,
tokenIssuer,
});
}
- return new EnvironmentHandler(envProviders);
+ return new EnvironmentHandler(providerId, envProviders);
}
diff --git a/plugins/auth-backend/src/providers/gitlab/provider.ts b/plugins/auth-backend/src/providers/gitlab/provider.ts
index 950c414750..af1d57fcce 100644
--- a/plugins/auth-backend/src/providers/gitlab/provider.ts
+++ b/plugins/auth-backend/src/providers/gitlab/provider.ts
@@ -142,6 +142,7 @@ export function createGitlabProvider(
logger: Logger,
tokenIssuer: TokenIssuer,
) {
+ const providerId = 'gitlab';
const envProviders: EnvironmentHandlers = {};
for (const [env, envConfig] of Object.entries(providerConfig)) {
@@ -152,12 +153,10 @@ export function createGitlabProvider(
clientSecret,
audience,
} = (envConfig as unknown) as OAuthProviderConfig;
- const callbackURLParam = `?env=${env}`;
-
const opts = {
clientID: clientId,
clientSecret: clientSecret,
- callbackURL: `${baseUrl}/gitlab/handler/frame${callbackURLParam}`,
+ callbackURL: `${baseUrl}/${providerId}/handler/frame?env=${env}`,
baseURL: audience,
};
@@ -176,12 +175,12 @@ export function createGitlabProvider(
envProviders[env] = new OAuthProvider(new GitlabAuthProvider(opts), {
disableRefresh: true,
- providerId: 'gitlab',
+ providerId,
secure,
baseUrl,
appOrigin,
tokenIssuer,
});
}
- return new EnvironmentHandler(envProviders);
+ return new EnvironmentHandler(providerId, envProviders);
}
diff --git a/plugins/auth-backend/src/providers/google/provider.ts b/plugins/auth-backend/src/providers/google/provider.ts
index 04705b66c1..3023c09886 100644
--- a/plugins/auth-backend/src/providers/google/provider.ts
+++ b/plugins/auth-backend/src/providers/google/provider.ts
@@ -154,16 +154,16 @@ export function createGoogleProvider(
logger: Logger,
tokenIssuer: TokenIssuer,
) {
+ const providerId = 'google';
const envProviders: EnvironmentHandlers = {};
for (const [env, envConfig] of Object.entries(providerConfig)) {
const config = (envConfig as unknown) as OAuthProviderConfig;
const { secure, appOrigin } = config;
- const callbackURLParam = `?env=${env}`;
const opts = {
clientID: config.clientId,
clientSecret: config.clientSecret,
- callbackURL: `${baseUrl}/google/handler/frame${callbackURLParam}`,
+ callbackURL: `${baseUrl}/${providerId}/handler/frame?env=${env}`,
};
if (!opts.clientID || !opts.clientSecret) {
@@ -181,12 +181,12 @@ export function createGoogleProvider(
envProviders[env] = new OAuthProvider(new GoogleAuthProvider(opts), {
disableRefresh: false,
- providerId: 'google',
+ providerId,
secure,
baseUrl,
appOrigin,
tokenIssuer,
});
}
- return new EnvironmentHandler(envProviders);
+ return new EnvironmentHandler(providerId, envProviders);
}
diff --git a/plugins/auth-backend/src/providers/oauth2/provider.ts b/plugins/auth-backend/src/providers/oauth2/provider.ts
index 1b5ee6d17e..60b6bc605b 100644
--- a/plugins/auth-backend/src/providers/oauth2/provider.ts
+++ b/plugins/auth-backend/src/providers/oauth2/provider.ts
@@ -152,16 +152,16 @@ export function createOAuth2Provider(
logger: Logger,
tokenIssuer: TokenIssuer,
) {
+ const providerId = 'oauth2';
const envProviders: EnvironmentHandlers = {};
for (const [env, envConfig] of Object.entries(providerConfig)) {
const config = (envConfig as unknown) as GenericOAuth2ProviderConfig;
const { secure, appOrigin } = config;
- const callbackURLParam = `?env=${env}`;
const opts = {
clientID: config.clientId,
clientSecret: config.clientSecret,
- callbackURL: `${baseUrl}/oauth2/handler/frame${callbackURLParam}`,
+ callbackURL: `${baseUrl}/${providerId}/handler/frame?env=${env}`,
authorizationURL: config.authorizationURL,
tokenURL: config.tokenURL,
};
@@ -186,7 +186,7 @@ export function createOAuth2Provider(
envProviders[env] = new OAuthProvider(new OAuth2AuthProvider(opts), {
disableRefresh: false,
- providerId: 'oauth2',
+ providerId,
secure,
baseUrl,
appOrigin,
@@ -194,5 +194,5 @@ export function createOAuth2Provider(
});
}
- return new EnvironmentHandler(envProviders);
+ return new EnvironmentHandler(providerId, envProviders);
}
diff --git a/plugins/auth-backend/src/providers/okta/provider.ts b/plugins/auth-backend/src/providers/okta/provider.ts
index e73843bb0c..01d7684e97 100644
--- a/plugins/auth-backend/src/providers/okta/provider.ts
+++ b/plugins/auth-backend/src/providers/okta/provider.ts
@@ -47,17 +47,16 @@ type PrivateInfo = {
};
export class OktaAuthProvider implements OAuthProviderHandlers {
-
private readonly _strategy: any;
- /**
+ /**
* Due to passport-okta-oauth forcing options.state = true,
* passport-oauth2 requires express-session to be installed
* so that the 'state' parameter of the oauth2 flow can be stored.
* This implementation of StateStore matches the NullStore found within
* passport-oauth2, which is the StateStore implementation used when options.state = false,
* allowing us to avoid using express-session in order to integrate with Okta.
- */
+ */
private _store: StateStore = {
store(_req: express.Request, cb: any) {
cb(null, null);
@@ -65,25 +64,27 @@ export class OktaAuthProvider implements OAuthProviderHandlers {
verify(_req: express.Request, _state: string, cb: any) {
cb(null, true);
},
- }
+ };
constructor(options: OAuthProviderOptions) {
- this._strategy = new OktaStrategy({
- passReqToCallback: false as true,
- ...options,
- store: this._store,
- response_type: 'code',
- }, (
- accessToken: any,
- refreshToken: any,
- params: any,
- rawProfile: passport.Profile,
- done: PassportDoneCallback,
- ) => {
- const profile = makeProfileInfo(rawProfile, params.id_token);
+ this._strategy = new OktaStrategy(
+ {
+ passReqToCallback: false as true,
+ ...options,
+ store: this._store,
+ response_type: 'code',
+ },
+ (
+ accessToken: any,
+ refreshToken: any,
+ params: any,
+ rawProfile: passport.Profile,
+ done: PassportDoneCallback,
+ ) => {
+ const profile = makeProfileInfo(rawProfile, params.id_token);
- done(
- undefined,
+ done(
+ undefined,
{
providerInfo: {
idToken: params.id_token,
@@ -96,13 +97,14 @@ export class OktaAuthProvider implements OAuthProviderHandlers {
{
refreshToken,
},
- )
- });
+ );
+ },
+ );
}
async start(
req: express.Request,
- options: Record
+ options: Record,
): Promise {
const providerOptions = {
...options,
@@ -113,7 +115,7 @@ export class OktaAuthProvider implements OAuthProviderHandlers {
}
async handler(
- req: express.Request
+ req: express.Request,
): Promise<{ response: OAuthResponse; refreshToken: string }> {
const { response, privateInfo } = await executeFrameHandlerStrategy<
OAuthResponse,
@@ -148,7 +150,6 @@ export class OktaAuthProvider implements OAuthProviderHandlers {
},
profile,
});
-
}
private async populateIdentity(
@@ -173,17 +174,17 @@ export function createOktaProvider(
logger: Logger,
tokenIssuer: TokenIssuer,
) {
+ const providerId = 'okta';
const envProviders: EnvironmentHandlers = {};
for (const [env, envConfig] of Object.entries(providerConfig)) {
const config = (envConfig as unknown) as OAuthProviderConfig;
const { secure, appOrigin } = config;
- const callbackURLParam = `?env=${env}`;
const opts = {
audience: config.audience,
clientID: config.clientId,
clientSecret: config.clientSecret,
- callbackURL: `${baseUrl}/okta/handler/frame${callbackURLParam}`,
+ callbackURL: `${baseUrl}/${providerId}/handler/frame?env=${env}`,
};
if (!opts.clientID || !opts.clientSecret || !opts.audience) {
@@ -201,7 +202,7 @@ export function createOktaProvider(
envProviders[env] = new OAuthProvider(new OktaAuthProvider(opts), {
disableRefresh: false,
- providerId: 'okta',
+ providerId,
secure,
baseUrl,
appOrigin,
@@ -209,5 +210,5 @@ export function createOktaProvider(
});
}
- return new EnvironmentHandler(envProviders);
+ return new EnvironmentHandler(providerId, envProviders);
}
diff --git a/plugins/auth-backend/src/providers/saml/provider.ts b/plugins/auth-backend/src/providers/saml/provider.ts
index 68b84c7e33..40c80de4e4 100644
--- a/plugins/auth-backend/src/providers/saml/provider.ts
+++ b/plugins/auth-backend/src/providers/saml/provider.ts
@@ -147,5 +147,5 @@ export function createSamlProvider(
envProviders[env] = new SamlAuthProvider(opts);
}
- return new EnvironmentHandler(envProviders);
+ return new EnvironmentHandler('saml', envProviders);
}