Read auth providers in backend and frontend from app-config yaml
This commit is contained in:
@@ -24,6 +24,11 @@ import { createOAuth2Provider } from './oauth2';
|
||||
import { createOktaProvider } from './okta';
|
||||
import { createSamlProvider } from './saml';
|
||||
import { AuthProviderConfig, AuthProviderFactory } from './types';
|
||||
import { Config } from '@backstage/config';
|
||||
import {
|
||||
EnvironmentHandlers,
|
||||
EnvironmentHandler,
|
||||
} from '../lib/EnvironmentHandler';
|
||||
|
||||
const factories: { [providerId: string]: AuthProviderFactory } = {
|
||||
google: createGoogleProvider,
|
||||
@@ -37,7 +42,7 @@ const factories: { [providerId: string]: AuthProviderFactory } = {
|
||||
export const createAuthProviderRouter = (
|
||||
providerId: string,
|
||||
globalConfig: AuthProviderConfig,
|
||||
providerConfig: any, // TODO: make this a config reader object of sorts
|
||||
providerConfig: Config,
|
||||
logger: Logger,
|
||||
issuer: TokenIssuer,
|
||||
) => {
|
||||
@@ -46,17 +51,28 @@ export const createAuthProviderRouter = (
|
||||
throw Error(`No auth provider available for '${providerId}'`);
|
||||
}
|
||||
|
||||
const provider = factory(globalConfig, providerConfig, logger, issuer);
|
||||
|
||||
const router = Router();
|
||||
router.get('/start', provider.start.bind(provider));
|
||||
router.get('/handler/frame', provider.frameHandler.bind(provider));
|
||||
router.post('/handler/frame', provider.frameHandler.bind(provider));
|
||||
if (provider.logout) {
|
||||
router.post('/logout', provider.logout.bind(provider));
|
||||
const envs = providerConfig.keys();
|
||||
const envProviders: EnvironmentHandlers = {};
|
||||
|
||||
for (const env of envs) {
|
||||
const envConfig = providerConfig.getConfig(env);
|
||||
const provider = factory(globalConfig, env, envConfig, logger, issuer);
|
||||
if (provider) {
|
||||
envProviders[env] = provider;
|
||||
}
|
||||
}
|
||||
if (provider.refresh) {
|
||||
router.get('/refresh', provider.refresh.bind(provider));
|
||||
|
||||
const handler = new EnvironmentHandler(providerId, envProviders);
|
||||
|
||||
router.get('/start', handler.start.bind(handler));
|
||||
router.get('/handler/frame', handler.frameHandler.bind(handler));
|
||||
router.post('/handler/frame', handler.frameHandler.bind(handler));
|
||||
if (handler.logout) {
|
||||
router.post('/logout', handler.logout.bind(handler));
|
||||
}
|
||||
if (handler.refresh) {
|
||||
router.get('/refresh', handler.refresh.bind(handler));
|
||||
}
|
||||
|
||||
return router;
|
||||
|
||||
@@ -25,20 +25,15 @@ import {
|
||||
OAuthProviderHandlers,
|
||||
AuthProviderConfig,
|
||||
RedirectInfo,
|
||||
EnvironmentProviderConfig,
|
||||
OAuthProviderOptions,
|
||||
OAuthProviderConfig,
|
||||
OAuthResponse,
|
||||
PassportDoneCallback,
|
||||
} from '../types';
|
||||
import { OAuthProvider } from '../../lib/OAuthProvider';
|
||||
import {
|
||||
EnvironmentHandlers,
|
||||
EnvironmentHandler,
|
||||
} from '../../lib/EnvironmentHandler';
|
||||
import { Logger } from 'winston';
|
||||
import { TokenIssuer } from '../../identity';
|
||||
import passport from 'passport';
|
||||
import { Config } from '@backstage/config';
|
||||
|
||||
export class GithubAuthProvider implements OAuthProviderHandlers {
|
||||
private readonly _strategy: GithubStrategy;
|
||||
@@ -131,44 +126,43 @@ export class GithubAuthProvider implements OAuthProviderHandlers {
|
||||
|
||||
export function createGithubProvider(
|
||||
{ baseUrl }: AuthProviderConfig,
|
||||
providerConfig: EnvironmentProviderConfig,
|
||||
env: string,
|
||||
envConfig: Config,
|
||||
logger: Logger,
|
||||
tokenIssuer: TokenIssuer,
|
||||
) {
|
||||
const providerId = 'github';
|
||||
const envProviders: EnvironmentHandlers = {};
|
||||
const secure = envConfig.getBoolean('secure');
|
||||
const appOrigin = envConfig.getString('appOrigin');
|
||||
const clientID = envConfig.getOptionalString('clientId');
|
||||
const clientSecret = envConfig.getOptionalString('clientSecret');
|
||||
const callbackURL = `${baseUrl}/${providerId}/handler/frame?env=${env}`;
|
||||
|
||||
for (const [env, envConfig] of Object.entries(providerConfig)) {
|
||||
const config = (envConfig as unknown) as OAuthProviderConfig;
|
||||
const { secure, appOrigin } = config;
|
||||
const opts = {
|
||||
clientID: config.clientId,
|
||||
clientSecret: config.clientSecret,
|
||||
callbackURL: `${baseUrl}/${providerId}/handler/frame?env=${env}`,
|
||||
};
|
||||
const opts = {
|
||||
clientID,
|
||||
clientSecret,
|
||||
callbackURL,
|
||||
};
|
||||
|
||||
if (!opts.clientID || !opts.clientSecret) {
|
||||
if (process.env.NODE_ENV !== 'development') {
|
||||
throw new Error(
|
||||
'Failed to initialize Github auth provider, set AUTH_GITHUB_CLIENT_ID and AUTH_GITHUB_CLIENT_SECRET env vars',
|
||||
);
|
||||
}
|
||||
|
||||
logger.warn(
|
||||
'Github auth provider disabled, set AUTH_GITHUB_CLIENT_ID and AUTH_GITHUB_CLIENT_SECRET env vars to enable',
|
||||
if (!opts.clientID || !opts.clientSecret) {
|
||||
if (process.env.NODE_ENV !== 'development') {
|
||||
throw new Error(
|
||||
'Failed to initialize Github auth provider, set AUTH_GITHUB_CLIENT_ID and AUTH_GITHUB_CLIENT_SECRET env vars',
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
envProviders[env] = new OAuthProvider(new GithubAuthProvider(opts), {
|
||||
disableRefresh: true,
|
||||
persistScopes: true,
|
||||
providerId,
|
||||
secure,
|
||||
baseUrl,
|
||||
appOrigin,
|
||||
tokenIssuer,
|
||||
});
|
||||
logger.warn(
|
||||
'Github auth provider disabled, set AUTH_GITHUB_CLIENT_ID and AUTH_GITHUB_CLIENT_SECRET env vars to enable',
|
||||
);
|
||||
return undefined;
|
||||
}
|
||||
return new EnvironmentHandler(providerId, envProviders);
|
||||
return new OAuthProvider(new GithubAuthProvider(opts), {
|
||||
disableRefresh: true,
|
||||
persistScopes: true,
|
||||
providerId,
|
||||
secure,
|
||||
baseUrl,
|
||||
appOrigin,
|
||||
tokenIssuer,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -25,20 +25,15 @@ import {
|
||||
OAuthProviderHandlers,
|
||||
AuthProviderConfig,
|
||||
RedirectInfo,
|
||||
EnvironmentProviderConfig,
|
||||
OAuthProviderOptions,
|
||||
OAuthProviderConfig,
|
||||
OAuthResponse,
|
||||
PassportDoneCallback,
|
||||
} from '../types';
|
||||
import { OAuthProvider } from '../../lib/OAuthProvider';
|
||||
import {
|
||||
EnvironmentHandlers,
|
||||
EnvironmentHandler,
|
||||
} from '../../lib/EnvironmentHandler';
|
||||
import { Logger } from 'winston';
|
||||
import { TokenIssuer } from '../../identity';
|
||||
import passport from 'passport';
|
||||
import { Config } from '@backstage/config';
|
||||
|
||||
export class GitlabAuthProvider implements OAuthProviderHandlers {
|
||||
private readonly _strategy: GitlabStrategy;
|
||||
@@ -138,49 +133,45 @@ export class GitlabAuthProvider implements OAuthProviderHandlers {
|
||||
|
||||
export function createGitlabProvider(
|
||||
{ baseUrl }: AuthProviderConfig,
|
||||
providerConfig: EnvironmentProviderConfig,
|
||||
env: string,
|
||||
envConfig: Config,
|
||||
logger: Logger,
|
||||
tokenIssuer: TokenIssuer,
|
||||
) {
|
||||
const providerId = 'gitlab';
|
||||
const envProviders: EnvironmentHandlers = {};
|
||||
const secure = envConfig.getBoolean('secure');
|
||||
const appOrigin = envConfig.getString('appOrigin');
|
||||
const clientID = envConfig.getOptionalString('clientId');
|
||||
const clientSecret = envConfig.getOptionalString('clientSecret');
|
||||
const audience = envConfig.getOptionalString('audience');
|
||||
const baseURL = audience || 'https://gitlab.com';
|
||||
const callbackURL = `${baseUrl}/${providerId}/handler/frame?env=${env}`;
|
||||
|
||||
for (const [env, envConfig] of Object.entries(providerConfig)) {
|
||||
const {
|
||||
secure,
|
||||
appOrigin,
|
||||
clientId,
|
||||
clientSecret,
|
||||
audience,
|
||||
} = (envConfig as unknown) as OAuthProviderConfig;
|
||||
const opts = {
|
||||
clientID: clientId,
|
||||
clientSecret: clientSecret,
|
||||
callbackURL: `${baseUrl}/${providerId}/handler/frame?env=${env}`,
|
||||
baseURL: audience,
|
||||
};
|
||||
const opts = {
|
||||
clientID,
|
||||
clientSecret,
|
||||
callbackURL,
|
||||
baseURL,
|
||||
};
|
||||
|
||||
if (!opts.clientID || !opts.clientSecret) {
|
||||
if (process.env.NODE_ENV !== 'development') {
|
||||
throw new Error(
|
||||
'Failed to initialize Gitlab auth provider, set AUTH_GITLAB_CLIENT_ID and AUTH_GITLAB_CLIENT_SECRET env vars',
|
||||
);
|
||||
}
|
||||
|
||||
logger.warn(
|
||||
'Gitlab auth provider disabled, set AUTH_GITLAB_CLIENT_ID and AUTH_GITLAB_CLIENT_SECRET env vars to enable',
|
||||
if (!opts.clientID || !opts.clientSecret) {
|
||||
if (process.env.NODE_ENV !== 'development') {
|
||||
throw new Error(
|
||||
'Failed to initialize Gitlab auth provider, set AUTH_GITLAB_CLIENT_ID and AUTH_GITLAB_CLIENT_SECRET env vars',
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
envProviders[env] = new OAuthProvider(new GitlabAuthProvider(opts), {
|
||||
disableRefresh: true,
|
||||
providerId,
|
||||
secure,
|
||||
baseUrl,
|
||||
appOrigin,
|
||||
tokenIssuer,
|
||||
});
|
||||
logger.warn(
|
||||
'Gitlab auth provider disabled, set AUTH_GITLAB_CLIENT_ID and AUTH_GITLAB_CLIENT_SECRET env vars to enable',
|
||||
);
|
||||
return undefined;
|
||||
}
|
||||
return new EnvironmentHandler(providerId, envProviders);
|
||||
return new OAuthProvider(new GitlabAuthProvider(opts), {
|
||||
disableRefresh: true,
|
||||
providerId,
|
||||
secure,
|
||||
baseUrl,
|
||||
appOrigin,
|
||||
tokenIssuer,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -27,20 +27,15 @@ import {
|
||||
OAuthProviderHandlers,
|
||||
RedirectInfo,
|
||||
AuthProviderConfig,
|
||||
EnvironmentProviderConfig,
|
||||
OAuthProviderOptions,
|
||||
OAuthProviderConfig,
|
||||
OAuthResponse,
|
||||
PassportDoneCallback,
|
||||
} from '../types';
|
||||
import { OAuthProvider } from '../../lib/OAuthProvider';
|
||||
import passport from 'passport';
|
||||
import {
|
||||
EnvironmentHandler,
|
||||
EnvironmentHandlers,
|
||||
} from '../../lib/EnvironmentHandler';
|
||||
import { Logger } from 'winston';
|
||||
import { TokenIssuer } from '../../identity';
|
||||
import { Config } from '@backstage/config';
|
||||
|
||||
type PrivateInfo = {
|
||||
refreshToken: string;
|
||||
@@ -150,43 +145,42 @@ export class GoogleAuthProvider implements OAuthProviderHandlers {
|
||||
|
||||
export function createGoogleProvider(
|
||||
{ baseUrl }: AuthProviderConfig,
|
||||
providerConfig: EnvironmentProviderConfig,
|
||||
env: string,
|
||||
envConfig: Config,
|
||||
logger: Logger,
|
||||
tokenIssuer: TokenIssuer,
|
||||
) {
|
||||
const providerId = 'google';
|
||||
const envProviders: EnvironmentHandlers = {};
|
||||
const secure = envConfig.getBoolean('secure');
|
||||
const appOrigin = envConfig.getString('appOrigin');
|
||||
const clientID = envConfig.getString('clientId');
|
||||
const clientSecret = envConfig.getString('clientSecret');
|
||||
const callbackURL = `${baseUrl}/${providerId}/handler/frame?env=${env}`;
|
||||
|
||||
for (const [env, envConfig] of Object.entries(providerConfig)) {
|
||||
const config = (envConfig as unknown) as OAuthProviderConfig;
|
||||
const { secure, appOrigin } = config;
|
||||
const opts = {
|
||||
clientID: config.clientId,
|
||||
clientSecret: config.clientSecret,
|
||||
callbackURL: `${baseUrl}/${providerId}/handler/frame?env=${env}`,
|
||||
};
|
||||
const opts = {
|
||||
clientID,
|
||||
clientSecret,
|
||||
callbackURL,
|
||||
};
|
||||
|
||||
if (!opts.clientID || !opts.clientSecret) {
|
||||
if (process.env.NODE_ENV !== 'development') {
|
||||
throw new Error(
|
||||
'Failed to initialize Google auth provider, set AUTH_GOOGLE_CLIENT_ID and AUTH_GOOGLE_CLIENT_SECRET env vars',
|
||||
);
|
||||
}
|
||||
|
||||
logger.warn(
|
||||
'Google auth provider disabled, set AUTH_GOOGLE_CLIENT_ID and AUTH_GOOGLE_CLIENT_SECRET env vars to enable',
|
||||
if (!opts.clientID || !opts.clientSecret) {
|
||||
if (process.env.NODE_ENV !== 'development') {
|
||||
throw new Error(
|
||||
'Failed to initialize Google auth provider, set AUTH_GOOGLE_CLIENT_ID and AUTH_GOOGLE_CLIENT_SECRET env vars',
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
envProviders[env] = new OAuthProvider(new GoogleAuthProvider(opts), {
|
||||
disableRefresh: false,
|
||||
providerId,
|
||||
secure,
|
||||
baseUrl,
|
||||
appOrigin,
|
||||
tokenIssuer,
|
||||
});
|
||||
logger.warn(
|
||||
'Google auth provider disabled, set AUTH_GOOGLE_CLIENT_ID and AUTH_GOOGLE_CLIENT_SECRET env vars to enable',
|
||||
);
|
||||
return undefined;
|
||||
}
|
||||
return new EnvironmentHandler(providerId, envProviders);
|
||||
return new OAuthProvider(new GoogleAuthProvider(opts), {
|
||||
disableRefresh: false,
|
||||
providerId,
|
||||
secure,
|
||||
baseUrl,
|
||||
appOrigin,
|
||||
tokenIssuer,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -19,10 +19,6 @@ import passport from 'passport';
|
||||
import { Strategy as OAuth2Strategy } from 'passport-oauth2';
|
||||
import { Logger } from 'winston';
|
||||
import { TokenIssuer } from '../../identity';
|
||||
import {
|
||||
EnvironmentHandler,
|
||||
EnvironmentHandlers,
|
||||
} from '../../lib/EnvironmentHandler';
|
||||
import { OAuthProvider } from '../../lib/OAuthProvider';
|
||||
import {
|
||||
executeFetchUserProfileStrategy,
|
||||
@@ -33,14 +29,13 @@ import {
|
||||
} from '../../lib/PassportStrategyHelper';
|
||||
import {
|
||||
AuthProviderConfig,
|
||||
EnvironmentProviderConfig,
|
||||
GenericOAuth2ProviderConfig,
|
||||
GenericOAuth2ProviderOptions,
|
||||
OAuthProviderHandlers,
|
||||
OAuthResponse,
|
||||
PassportDoneCallback,
|
||||
RedirectInfo,
|
||||
} from '../types';
|
||||
import { Config } from '@backstage/config';
|
||||
|
||||
type PrivateInfo = {
|
||||
refreshToken: string;
|
||||
@@ -148,51 +143,51 @@ export class OAuth2AuthProvider implements OAuthProviderHandlers {
|
||||
|
||||
export function createOAuth2Provider(
|
||||
{ baseUrl }: AuthProviderConfig,
|
||||
providerConfig: EnvironmentProviderConfig,
|
||||
env: string,
|
||||
envConfig: Config,
|
||||
logger: Logger,
|
||||
tokenIssuer: TokenIssuer,
|
||||
) {
|
||||
const providerId = 'oauth2';
|
||||
const envProviders: EnvironmentHandlers = {};
|
||||
const secure = envConfig.getBoolean('secure');
|
||||
const appOrigin = envConfig.getString('appOrigin');
|
||||
const clientID = envConfig.getOptionalString('clientId');
|
||||
const clientSecret = envConfig.getOptionalString('clientSecret');
|
||||
const callbackURL = `${baseUrl}/${providerId}/handler/frame?env=${env}`;
|
||||
const authorizationURL = envConfig.getOptionalString('authorizationURL');
|
||||
const tokenURL = envConfig.getOptionalString('tokenURL');
|
||||
|
||||
for (const [env, envConfig] of Object.entries(providerConfig)) {
|
||||
const config = (envConfig as unknown) as GenericOAuth2ProviderConfig;
|
||||
const { secure, appOrigin } = config;
|
||||
const opts = {
|
||||
clientID: config.clientId,
|
||||
clientSecret: config.clientSecret,
|
||||
callbackURL: `${baseUrl}/${providerId}/handler/frame?env=${env}`,
|
||||
authorizationURL: config.authorizationURL,
|
||||
tokenURL: config.tokenURL,
|
||||
};
|
||||
const opts = {
|
||||
clientID,
|
||||
clientSecret,
|
||||
callbackURL,
|
||||
authorizationURL,
|
||||
tokenURL,
|
||||
};
|
||||
|
||||
if (
|
||||
!opts.clientID ||
|
||||
!opts.clientSecret ||
|
||||
!opts.authorizationURL ||
|
||||
!opts.tokenURL
|
||||
) {
|
||||
if (process.env.NODE_ENV !== 'development') {
|
||||
throw new Error(
|
||||
'Failed to initialize OAuth2 auth provider, set AUTH_OAUTH2_CLIENT_ID, AUTH_OAUTH2_CLIENT_SECRET, AUTH_OAUTH2_AUTH_URL, and AUTH_OAUTH2_TOKEN_URL env vars',
|
||||
);
|
||||
}
|
||||
|
||||
logger.warn(
|
||||
'OAuth2 auth provider disabled, set AUTH_OAUTH2_CLIENT_ID, AUTH_OAUTH2_CLIENT_SECRET, AUTH_OAUTH2_AUTH_URL, and AUTH_OAUTH2_TOKEN_URL env vars to enable',
|
||||
if (
|
||||
!opts.clientID ||
|
||||
!opts.clientSecret ||
|
||||
!opts.authorizationURL ||
|
||||
!opts.tokenURL
|
||||
) {
|
||||
if (process.env.NODE_ENV !== 'development') {
|
||||
throw new Error(
|
||||
'Failed to initialize OAuth2 auth provider, set AUTH_OAUTH2_CLIENT_ID, AUTH_OAUTH2_CLIENT_SECRET, AUTH_OAUTH2_AUTH_URL, and AUTH_OAUTH2_TOKEN_URL env vars',
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
envProviders[env] = new OAuthProvider(new OAuth2AuthProvider(opts), {
|
||||
disableRefresh: false,
|
||||
providerId,
|
||||
secure,
|
||||
baseUrl,
|
||||
appOrigin,
|
||||
tokenIssuer,
|
||||
});
|
||||
logger.warn(
|
||||
'OAuth2 auth provider disabled, set AUTH_OAUTH2_CLIENT_ID, AUTH_OAUTH2_CLIENT_SECRET, AUTH_OAUTH2_AUTH_URL, and AUTH_OAUTH2_TOKEN_URL env vars to enable',
|
||||
);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return new EnvironmentHandler(providerId, envProviders);
|
||||
return new OAuthProvider(new OAuth2AuthProvider(opts), {
|
||||
disableRefresh: false,
|
||||
providerId,
|
||||
secure,
|
||||
baseUrl,
|
||||
appOrigin,
|
||||
tokenIssuer,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -28,19 +28,14 @@ import {
|
||||
OAuthProviderHandlers,
|
||||
RedirectInfo,
|
||||
AuthProviderConfig,
|
||||
EnvironmentProviderConfig,
|
||||
OAuthProviderOptions,
|
||||
OAuthProviderConfig,
|
||||
OAuthResponse,
|
||||
PassportDoneCallback,
|
||||
} from '../types';
|
||||
import {
|
||||
EnvironmentHandler,
|
||||
EnvironmentHandlers,
|
||||
} from '../../lib/EnvironmentHandler';
|
||||
import { Logger } from 'winston';
|
||||
import { StateStore } from 'passport-oauth2';
|
||||
import { TokenIssuer } from '../../identity';
|
||||
import { Config } from '@backstage/config';
|
||||
|
||||
type PrivateInfo = {
|
||||
refreshToken: string;
|
||||
@@ -170,45 +165,44 @@ export class OktaAuthProvider implements OAuthProviderHandlers {
|
||||
|
||||
export function createOktaProvider(
|
||||
{ baseUrl }: AuthProviderConfig,
|
||||
providerConfig: EnvironmentProviderConfig,
|
||||
env: string,
|
||||
envConfig: Config,
|
||||
logger: Logger,
|
||||
tokenIssuer: TokenIssuer,
|
||||
) {
|
||||
const providerId = 'okta';
|
||||
const envProviders: EnvironmentHandlers = {};
|
||||
const secure = envConfig.getBoolean('secure');
|
||||
const appOrigin = envConfig.getString('appOrigin');
|
||||
const clientID = envConfig.getOptionalString('clientId');
|
||||
const clientSecret = envConfig.getOptionalString('clientSecret');
|
||||
const audience = envConfig.getOptionalString('audience');
|
||||
const callbackURL = `${baseUrl}/${providerId}/handler/frame?env=${env}`;
|
||||
|
||||
for (const [env, envConfig] of Object.entries(providerConfig)) {
|
||||
const config = (envConfig as unknown) as OAuthProviderConfig;
|
||||
const { secure, appOrigin } = config;
|
||||
const opts = {
|
||||
audience: config.audience,
|
||||
clientID: config.clientId,
|
||||
clientSecret: config.clientSecret,
|
||||
callbackURL: `${baseUrl}/${providerId}/handler/frame?env=${env}`,
|
||||
};
|
||||
const opts = {
|
||||
audience,
|
||||
clientID,
|
||||
clientSecret,
|
||||
callbackURL,
|
||||
};
|
||||
|
||||
if (!opts.clientID || !opts.clientSecret || !opts.audience) {
|
||||
if (process.env.NODE_ENV !== 'development') {
|
||||
throw new Error(
|
||||
'Failed to initialize Okta auth provider, set AUTH_OKTA_CLIENT_ID, AUTH_OKTA_CLIENT_SECRET, and AUTH_OKTA_AUDIENCE env vars',
|
||||
);
|
||||
}
|
||||
|
||||
logger.warn(
|
||||
'Okta auth provider disabled, set AUTH_OKTA_CLIENT_ID, AUTH_OKTA_CLIENT_SECRET, and AUTH_OKTA_AUDIENCE env vars to enable',
|
||||
if (!opts.clientID || !opts.clientSecret || !opts.audience) {
|
||||
if (process.env.NODE_ENV !== 'development') {
|
||||
throw new Error(
|
||||
'Failed to initialize Okta auth provider, set AUTH_OKTA_CLIENT_ID, AUTH_OKTA_CLIENT_SECRET, and AUTH_OKTA_AUDIENCE env vars',
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
envProviders[env] = new OAuthProvider(new OktaAuthProvider(opts), {
|
||||
disableRefresh: false,
|
||||
providerId,
|
||||
secure,
|
||||
baseUrl,
|
||||
appOrigin,
|
||||
tokenIssuer,
|
||||
});
|
||||
logger.warn(
|
||||
'Okta auth provider disabled, set AUTH_OKTA_CLIENT_ID, AUTH_OKTA_CLIENT_SECRET, and AUTH_OKTA_AUDIENCE env vars to enable',
|
||||
);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return new EnvironmentHandler(providerId, envProviders);
|
||||
return new OAuthProvider(new OktaAuthProvider(opts), {
|
||||
disableRefresh: false,
|
||||
providerId,
|
||||
secure,
|
||||
baseUrl,
|
||||
appOrigin,
|
||||
tokenIssuer,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -27,18 +27,13 @@ import {
|
||||
import {
|
||||
AuthProviderConfig,
|
||||
AuthProviderRouteHandlers,
|
||||
EnvironmentProviderConfig,
|
||||
SAMLProviderConfig,
|
||||
PassportDoneCallback,
|
||||
ProfileInfo,
|
||||
} from '../types';
|
||||
import { postMessageResponse } from '../../lib/OAuthProvider';
|
||||
import {
|
||||
EnvironmentHandlers,
|
||||
EnvironmentHandler,
|
||||
} from '../../lib/EnvironmentHandler';
|
||||
import { Logger } from 'winston';
|
||||
import { TokenIssuer } from '../../identity';
|
||||
import { Config } from '@backstage/config';
|
||||
|
||||
type SamlInfo = {
|
||||
userId: string;
|
||||
@@ -122,30 +117,25 @@ type SAMLProviderOptions = {
|
||||
|
||||
export function createSamlProvider(
|
||||
_authProviderConfig: AuthProviderConfig,
|
||||
providerConfig: EnvironmentProviderConfig,
|
||||
_env: string,
|
||||
envConfig: Config,
|
||||
logger: Logger,
|
||||
tokenIssuer: TokenIssuer,
|
||||
) {
|
||||
const envProviders: EnvironmentHandlers = {};
|
||||
const entryPoint = envConfig.getString('entryPoint');
|
||||
const issuer = envConfig.getString('issuer');
|
||||
const opts = {
|
||||
entryPoint,
|
||||
issuer,
|
||||
path: '/auth/saml/handler/frame',
|
||||
tokenIssuer,
|
||||
};
|
||||
|
||||
for (const [env, envConfig] of Object.entries(providerConfig)) {
|
||||
const config = (envConfig as unknown) as SAMLProviderConfig;
|
||||
const opts = {
|
||||
entryPoint: config.entryPoint,
|
||||
issuer: config.issuer,
|
||||
path: '/auth/saml/handler/frame',
|
||||
tokenIssuer,
|
||||
};
|
||||
|
||||
if (!opts.entryPoint || !opts.issuer) {
|
||||
logger.warn(
|
||||
'SAML auth provider disabled, set entryPoint and entryPoint in saml auth config to enable',
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
envProviders[env] = new SamlAuthProvider(opts);
|
||||
if (!opts.entryPoint || !opts.issuer) {
|
||||
logger.warn(
|
||||
'SAML auth provider disabled, set entryPoint and entryPoint in saml auth config to enable',
|
||||
);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return new EnvironmentHandler('saml', envProviders);
|
||||
return new SamlAuthProvider(opts);
|
||||
}
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
import express from 'express';
|
||||
import { Logger } from 'winston';
|
||||
import { TokenIssuer } from '../identity';
|
||||
import { Config } from '@backstage/config';
|
||||
import { OAuthProvider } from '../lib/OAuthProvider';
|
||||
import { SamlAuthProvider } from './saml/provider';
|
||||
|
||||
export type OAuthProviderOptions = {
|
||||
/**
|
||||
@@ -204,10 +207,11 @@ export interface AuthProviderRouteHandlers {
|
||||
|
||||
export type AuthProviderFactory = (
|
||||
globalConfig: AuthProviderConfig,
|
||||
providerConfig: EnvironmentProviderConfig,
|
||||
env: string,
|
||||
envConfig: Config,
|
||||
logger: Logger,
|
||||
issuer: TokenIssuer,
|
||||
) => AuthProviderRouteHandlers;
|
||||
) => OAuthProvider | SamlAuthProvider | undefined;
|
||||
|
||||
export type AuthResponse<ProviderInfo> = {
|
||||
providerInfo: ProviderInfo;
|
||||
|
||||
@@ -36,8 +36,6 @@ export async function createRouter(
|
||||
const router = Router();
|
||||
const logger = options.logger.child({ plugin: 'auth' });
|
||||
|
||||
const appUrl = new URL(options.config.getString('app.baseUrl'));
|
||||
const appOrigin = appUrl.origin;
|
||||
const backendUrl = options.config.getString('backend.baseUrl');
|
||||
const authUrl = `${backendUrl}/auth`;
|
||||
|
||||
@@ -57,71 +55,13 @@ export async function createRouter(
|
||||
router.use(bodyParser.urlencoded({ extended: false }));
|
||||
router.use(bodyParser.json());
|
||||
|
||||
const config = {
|
||||
backend: {
|
||||
baseUrl: backendUrl,
|
||||
},
|
||||
auth: {
|
||||
providers: {
|
||||
google: {
|
||||
development: {
|
||||
appOrigin,
|
||||
secure: false,
|
||||
clientId: process.env.AUTH_GOOGLE_CLIENT_ID!,
|
||||
clientSecret: process.env.AUTH_GOOGLE_CLIENT_SECRET!,
|
||||
},
|
||||
},
|
||||
github: {
|
||||
development: {
|
||||
appOrigin,
|
||||
secure: false,
|
||||
clientId: process.env.AUTH_GITHUB_CLIENT_ID!,
|
||||
clientSecret: process.env.AUTH_GITHUB_CLIENT_SECRET!,
|
||||
},
|
||||
},
|
||||
gitlab: {
|
||||
development: {
|
||||
appOrigin,
|
||||
secure: false,
|
||||
clientId: process.env.AUTH_GITLAB_CLIENT_ID!,
|
||||
clientSecret: process.env.AUTH_GITLAB_CLIENT_SECRET!,
|
||||
audience: process.env.GITLAB_BASE_URL! || 'https://gitlab.com',
|
||||
},
|
||||
},
|
||||
saml: {
|
||||
development: {
|
||||
entryPoint: 'http://localhost:7001/',
|
||||
issuer: 'passport-saml',
|
||||
},
|
||||
},
|
||||
okta: {
|
||||
development: {
|
||||
appOrigin,
|
||||
secure: false,
|
||||
clientId: process.env.AUTH_OKTA_CLIENT_ID!,
|
||||
clientSecret: process.env.AUTH_OKTA_CLIENT_SECRET!,
|
||||
audience: process.env.AUTH_OKTA_AUDIENCE,
|
||||
},
|
||||
},
|
||||
oauth2: {
|
||||
development: {
|
||||
appOrigin,
|
||||
secure: false,
|
||||
clientId: process.env.AUTH_OAUTH2_CLIENT_ID!,
|
||||
clientSecret: process.env.AUTH_OAUTH2_CLIENT_SECRET!,
|
||||
authorizationURL: process.env.AUTH_OAUTH2_AUTH_URL!,
|
||||
tokenURL: process.env.AUTH_OAUTH2_TOKEN_URL!,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
const providersConfig = options.config.getConfig('auth.providers');
|
||||
const providers = providersConfig.keys();
|
||||
|
||||
const providerConfigs = config.auth.providers;
|
||||
|
||||
for (const [providerId, providerConfig] of Object.entries(providerConfigs)) {
|
||||
for (const providerId of providers) {
|
||||
logger.info(`Configuring provider, ${providerId}`);
|
||||
try {
|
||||
const providerConfig = providersConfig.getConfig(providerId);
|
||||
const providerRouter = createAuthProviderRouter(
|
||||
providerId,
|
||||
{ baseUrl: authUrl },
|
||||
|
||||
Reference in New Issue
Block a user