Read auth providers in backend and frontend from app-config yaml

This commit is contained in:
Raghunandan
2020-07-17 13:24:30 +02:00
parent 3158c2390b
commit 60d3ecc695
14 changed files with 333 additions and 335 deletions
+69
View File
@@ -25,3 +25,72 @@ techdocs:
sentry:
organization: spotify
auth:
providers:
google:
development:
appOrigin: "http://localhost:3000/"
secure: false
clientId:
$secret:
env: AUTH_GOOGLE_CLIENT_ID
clientSecret:
$secret:
env: AUTH_GOOGLE_CLIENT_SECRET
github:
development:
appOrigin: "http://localhost:3000/"
secure: false
clientId:
$secret:
env: AUTH_GITHUB_CLIENT_ID
clientSecret:
$secret:
env: AUTH_GITHUB_CLIENT_SECRET
gitlab:
development:
appOrigin: "http://localhost:3000/"
secure: false
clientId:
$secret:
env: AUTH_GITLAB_CLIENT_ID
clientSecret:
$secret:
env: AUTH_GITLAB_CLIENT_SECRET
audience:
$secret:
env: GITLAB_BASE_URL
# saml:
# development:
# entryPoint: "http://localhost:7001/"
# issuer: "passport-saml"
okta:
development:
appOrigin: "http://localhost:3000/"
secure: false
clientId:
$secret:
env: AUTH_OKTA_CLIENT_ID
clientSecret:
$secret:
env: AUTH_OKTA_CLIENT_SECRET
audience:
$secret:
env: AUTH_OKTA_AUDIENCE
oauth2:
development:
appOrigin: "http://localhost:3000/"
secure: false
clientId:
$secret:
env: AUTH_OAUTH2_CLIENT_ID
clientSecret:
$secret:
env: AUTH_OAUTH2_CLIENT_SECRET
authorizationURL:
$secret:
env: AUTH_OAUTH2_AUTH_URL
tokenURL:
$secret:
env: AUTH_OAUTH2_TOKEN_URL
+9 -6
View File
@@ -19,6 +19,8 @@ import {
AlertDisplay,
OAuthRequestDialog,
SignInPage,
useApi,
configApiRef,
} from '@backstage/core';
import React, { FC } from 'react';
import Root from './components/Root';
@@ -30,12 +32,13 @@ const app = createApp({
apis,
plugins: Object.values(plugins),
components: {
SignInPage: props => (
<SignInPage
{...props}
providers={['guest', 'google', 'custom', 'okta', 'gitlab', 'github']}
/>
),
SignInPage: props => {
const configApi = useApi(configApiRef);
const providersConfig = configApi.getConfig('auth.providers');
const providers = providersConfig.keys();
return <SignInPage {...props} providers={['guest', ...providers]} />;
},
},
});
+1 -1
View File
@@ -58,7 +58,7 @@ function makeCreateEnv(loadedConfigs: AppConfig[]) {
}
async function main() {
const configs = await loadConfig();
const configs = await loadConfig({ shouldReadSecrets: true });
const configReader = ConfigReader.fromConfigs(configs);
const createEnv = makeCreateEnv(configs);
@@ -22,6 +22,7 @@ import {
oauth2ApiRef,
oktaAuthApiRef,
useApi,
configApiRef,
} from '@backstage/core-api';
import Collapse from '@material-ui/core/Collapse';
import SignOutIcon from '@material-ui/icons/MeetingRoom';
@@ -39,6 +40,9 @@ export function SidebarUserSettings() {
const { isOpen: sidebarOpen } = useContext(SidebarContext);
const [open, setOpen] = React.useState(false);
const identityApi = useApi(identityApiRef);
const configApi = useApi(configApiRef);
const providersConfig = configApi.getConfig('auth.providers');
const providers = providersConfig.keys();
// Close the provider list when sidebar collapse
useEffect(() => {
@@ -49,31 +53,41 @@ export function SidebarUserSettings() {
<>
<SidebarUserProfile open={open} setOpen={setOpen} />
<Collapse in={open} timeout="auto">
<OIDCProviderSettings
title="Google"
apiRef={googleAuthApiRef}
icon={Star}
/>
<OAuthProviderSettings
title="Github"
apiRef={githubAuthApiRef}
icon={Star}
/>
<OAuthProviderSettings
title="Gitlab"
apiRef={gitlabAuthApiRef}
icon={Star}
/>
<OIDCProviderSettings
title="Okta"
apiRef={oktaAuthApiRef}
icon={Star}
/>
<OIDCProviderSettings
title="YourOrg"
apiRef={oauth2ApiRef}
icon={Star}
/>
{providers.includes('google') && (
<OIDCProviderSettings
title="Google"
apiRef={googleAuthApiRef}
icon={Star}
/>
)}
{providers.includes('github') && (
<OAuthProviderSettings
title="Github"
apiRef={githubAuthApiRef}
icon={Star}
/>
)}
{providers.includes('gitlab') && (
<OAuthProviderSettings
title="Gitlab"
apiRef={gitlabAuthApiRef}
icon={Star}
/>
)}
{providers.includes('okta') && (
<OIDCProviderSettings
title="Okta"
apiRef={oktaAuthApiRef}
icon={Star}
/>
)}
{providers.includes('oauth2') && (
<OIDCProviderSettings
title="YourOrg"
apiRef={oauth2ApiRef}
icon={Star}
/>
)}
<SidebarItem
icon={SignOutIcon}
text="Sign Out"
@@ -33,19 +33,13 @@ import { SignInProvider } from './types';
const PROVIDER_STORAGE_KEY = '@backstage/core:SignInPage:provider';
// Separate list here to avoid exporting internal types
export type SignInProviderId =
| 'guest'
| 'google'
| 'gitlab'
| 'custom'
| 'okta'
| 'github';
export type SignInProviderId = 'guest' | string;
const signInProviders: { [id in SignInProviderId]: SignInProvider } = {
guest: guestProvider,
google: googleProvider,
gitlab: gitlabProvider,
custom: customProvider,
oauth2: customProvider,
okta: oktaProvider,
github: githubProvider,
};
+26 -10
View File
@@ -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);
}
+6 -2
View File
@@ -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;
+4 -64
View File
@@ -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 },