auth-backend: migrate all other providers to use integration helper
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
@@ -36,8 +36,8 @@ import {
|
||||
makeProfileInfo,
|
||||
PassportDoneCallback,
|
||||
} from '../../lib/passport';
|
||||
import { createAuthProviderIntegration } from '../createAuthProviderIntegration';
|
||||
import {
|
||||
AuthProviderFactory,
|
||||
AuthHandler,
|
||||
RedirectInfo,
|
||||
SignInResolver,
|
||||
@@ -245,52 +245,65 @@ export type BitbucketProviderOptions = {
|
||||
};
|
||||
};
|
||||
|
||||
export const createBitbucketProvider = (options?: {
|
||||
/**
|
||||
* The profile transformation function used to verify and convert the auth response
|
||||
* into the profile that will be presented to the user.
|
||||
*/
|
||||
authHandler?: AuthHandler<OAuthResult>;
|
||||
|
||||
/**
|
||||
* Configure sign-in for this provider, without it the provider can not be used to sign users in.
|
||||
*/
|
||||
signIn?: {
|
||||
/**
|
||||
* Auth provider integration for BitBucket auth
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const bitbucket = createAuthProviderIntegration({
|
||||
create(options?: {
|
||||
/**
|
||||
* Maps an auth result to a Backstage identity for the user.
|
||||
* The profile transformation function used to verify and convert the auth response
|
||||
* into the profile that will be presented to the user.
|
||||
*/
|
||||
resolver: SignInResolver<OAuthResult>;
|
||||
};
|
||||
}): AuthProviderFactory => {
|
||||
return ({ providerId, globalConfig, config, resolverContext }) =>
|
||||
OAuthEnvironmentHandler.mapConfig(config, envConfig => {
|
||||
const clientId = envConfig.getString('clientId');
|
||||
const clientSecret = envConfig.getString('clientSecret');
|
||||
const customCallbackUrl = envConfig.getOptionalString('callbackUrl');
|
||||
const callbackUrl =
|
||||
customCallbackUrl ||
|
||||
`${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
||||
authHandler?: AuthHandler<OAuthResult>;
|
||||
|
||||
const authHandler: AuthHandler<BitbucketOAuthResult> =
|
||||
options?.authHandler
|
||||
? options.authHandler
|
||||
: async ({ fullProfile, params }) => ({
|
||||
profile: makeProfileInfo(fullProfile, params.id_token),
|
||||
});
|
||||
/**
|
||||
* Configure sign-in for this provider, without it the provider can not be used to sign users in.
|
||||
*/
|
||||
signIn?: {
|
||||
/**
|
||||
* Maps an auth result to a Backstage identity for the user.
|
||||
*/
|
||||
resolver: SignInResolver<OAuthResult>;
|
||||
};
|
||||
}) {
|
||||
return ({ providerId, globalConfig, config, resolverContext }) =>
|
||||
OAuthEnvironmentHandler.mapConfig(config, envConfig => {
|
||||
const clientId = envConfig.getString('clientId');
|
||||
const clientSecret = envConfig.getString('clientSecret');
|
||||
const customCallbackUrl = envConfig.getOptionalString('callbackUrl');
|
||||
const callbackUrl =
|
||||
customCallbackUrl ||
|
||||
`${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
||||
|
||||
const provider = new BitbucketAuthProvider({
|
||||
clientId,
|
||||
clientSecret,
|
||||
callbackUrl,
|
||||
signInResolver: options?.signIn?.resolver,
|
||||
authHandler,
|
||||
resolverContext,
|
||||
const authHandler: AuthHandler<BitbucketOAuthResult> =
|
||||
options?.authHandler
|
||||
? options.authHandler
|
||||
: async ({ fullProfile, params }) => ({
|
||||
profile: makeProfileInfo(fullProfile, params.id_token),
|
||||
});
|
||||
|
||||
const provider = new BitbucketAuthProvider({
|
||||
clientId,
|
||||
clientSecret,
|
||||
callbackUrl,
|
||||
signInResolver: options?.signIn?.resolver,
|
||||
authHandler,
|
||||
resolverContext,
|
||||
});
|
||||
|
||||
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
||||
disableRefresh: false,
|
||||
providerId,
|
||||
callbackUrl,
|
||||
});
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
||||
disableRefresh: false,
|
||||
providerId,
|
||||
callbackUrl,
|
||||
});
|
||||
});
|
||||
};
|
||||
/**
|
||||
* @public
|
||||
* @deprecated Use `providers.bitbucket.create` instead
|
||||
*/
|
||||
export const createBitbucketProvider = bitbucket.create;
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
|
||||
import express from 'express';
|
||||
import { TokenPayload } from 'google-auth-library';
|
||||
import { createAuthProviderIntegration } from '../createAuthProviderIntegration';
|
||||
import { prepareBackstageIdentityResponse } from '../prepareBackstageIdentityResponse';
|
||||
import {
|
||||
AuthHandler,
|
||||
AuthProviderFactory,
|
||||
AuthProviderRouteHandlers,
|
||||
AuthResolverContext,
|
||||
SignInResolver,
|
||||
@@ -77,41 +77,49 @@ export class GcpIapProvider implements AuthProviderRouteHandlers {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an auth provider for Google Identity-Aware Proxy.
|
||||
* Auth provider integration for Google Identity-Aware Proxy auth
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export function createGcpIapProvider(options: {
|
||||
/**
|
||||
* The profile transformation function used to verify and convert the auth
|
||||
* response into the profile that will be presented to the user. The default
|
||||
* implementation just provides the authenticated email that the IAP
|
||||
* presented.
|
||||
*/
|
||||
authHandler?: AuthHandler<GcpIapResult>;
|
||||
|
||||
/**
|
||||
* Configures sign-in for this provider.
|
||||
*/
|
||||
signIn: {
|
||||
export const gcpIap = createAuthProviderIntegration({
|
||||
create(options: {
|
||||
/**
|
||||
* Maps an auth result to a Backstage identity for the user.
|
||||
* The profile transformation function used to verify and convert the auth
|
||||
* response into the profile that will be presented to the user. The default
|
||||
* implementation just provides the authenticated email that the IAP
|
||||
* presented.
|
||||
*/
|
||||
resolver: SignInResolver<GcpIapResult>;
|
||||
};
|
||||
}): AuthProviderFactory {
|
||||
return ({ config, resolverContext }) => {
|
||||
const audience = config.getString('audience');
|
||||
authHandler?: AuthHandler<GcpIapResult>;
|
||||
|
||||
const authHandler = options.authHandler ?? defaultAuthHandler;
|
||||
const signInResolver = options.signIn.resolver;
|
||||
const tokenValidator = createTokenValidator(audience);
|
||||
/**
|
||||
* Configures sign-in for this provider.
|
||||
*/
|
||||
signIn: {
|
||||
/**
|
||||
* Maps an auth result to a Backstage identity for the user.
|
||||
*/
|
||||
resolver: SignInResolver<GcpIapResult>;
|
||||
};
|
||||
}) {
|
||||
return ({ config, resolverContext }) => {
|
||||
const audience = config.getString('audience');
|
||||
|
||||
return new GcpIapProvider({
|
||||
authHandler,
|
||||
signInResolver,
|
||||
tokenValidator,
|
||||
resolverContext,
|
||||
});
|
||||
};
|
||||
}
|
||||
const authHandler = options.authHandler ?? defaultAuthHandler;
|
||||
const signInResolver = options.signIn.resolver;
|
||||
const tokenValidator = createTokenValidator(audience);
|
||||
|
||||
return new GcpIapProvider({
|
||||
authHandler,
|
||||
signInResolver,
|
||||
tokenValidator,
|
||||
resolverContext,
|
||||
});
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* @public
|
||||
* @deprecated Use `providers.gcpIap.create` instead
|
||||
*/
|
||||
export const createGcpIapProvider = gcpIap.create;
|
||||
|
||||
@@ -27,7 +27,6 @@ import {
|
||||
} from '../../lib/passport';
|
||||
import {
|
||||
RedirectInfo,
|
||||
AuthProviderFactory,
|
||||
AuthHandler,
|
||||
SignInResolver,
|
||||
StateEncoder,
|
||||
@@ -42,6 +41,7 @@ import {
|
||||
encodeState,
|
||||
OAuthRefreshRequest,
|
||||
} from '../../lib/oauth';
|
||||
import { createAuthProviderIntegration } from '../createAuthProviderIntegration';
|
||||
|
||||
const ACCESS_TOKEN_PREFIX = 'access-token.';
|
||||
|
||||
@@ -279,91 +279,106 @@ export type GithubProviderOptions = {
|
||||
stateEncoder?: StateEncoder;
|
||||
};
|
||||
|
||||
export const createGithubProvider = (options?: {
|
||||
/**
|
||||
* The profile transformation function used to verify and convert the auth response
|
||||
* into the profile that will be presented to the user.
|
||||
*/
|
||||
authHandler?: AuthHandler<GithubOAuthResult>;
|
||||
|
||||
/**
|
||||
* Configure sign-in for this provider, without it the provider can not be used to sign users in.
|
||||
*/
|
||||
signIn?: {
|
||||
/**
|
||||
* Auth provider integration for GitHub auth
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const github = createAuthProviderIntegration({
|
||||
create(options?: {
|
||||
/**
|
||||
* Maps an auth result to a Backstage identity for the user.
|
||||
* The profile transformation function used to verify and convert the auth response
|
||||
* into the profile that will be presented to the user.
|
||||
*/
|
||||
resolver: SignInResolver<GithubOAuthResult>;
|
||||
};
|
||||
authHandler?: AuthHandler<GithubOAuthResult>;
|
||||
|
||||
/**
|
||||
* The state encoder used to encode the 'state' parameter on the OAuth request.
|
||||
*
|
||||
* It should return a string that takes the state params (from the request), url encodes the params
|
||||
* and finally base64 encodes them.
|
||||
*
|
||||
* Providing your own stateEncoder will allow you to add addition parameters to the state field.
|
||||
*
|
||||
* It is typed as follows:
|
||||
* `export type StateEncoder = (input: OAuthState) => Promise<{encodedState: string}>;`
|
||||
*
|
||||
* Note: the stateEncoder must encode a 'nonce' value and an 'env' value. Without this, the OAuth flow will fail
|
||||
* (These two values will be set by the req.state by default)
|
||||
*
|
||||
* For more information, please see the helper module in ../../oauth/helpers #readState
|
||||
*/
|
||||
stateEncoder?: StateEncoder;
|
||||
}): AuthProviderFactory => {
|
||||
return ({ providerId, globalConfig, config, resolverContext }) =>
|
||||
OAuthEnvironmentHandler.mapConfig(config, envConfig => {
|
||||
const clientId = envConfig.getString('clientId');
|
||||
const clientSecret = envConfig.getString('clientSecret');
|
||||
const enterpriseInstanceUrl = envConfig
|
||||
.getOptionalString('enterpriseInstanceUrl')
|
||||
?.replace(/\/$/, '');
|
||||
const customCallbackUrl = envConfig.getOptionalString('callbackUrl');
|
||||
const authorizationUrl = enterpriseInstanceUrl
|
||||
? `${enterpriseInstanceUrl}/login/oauth/authorize`
|
||||
: undefined;
|
||||
const tokenUrl = enterpriseInstanceUrl
|
||||
? `${enterpriseInstanceUrl}/login/oauth/access_token`
|
||||
: undefined;
|
||||
const userProfileUrl = enterpriseInstanceUrl
|
||||
? `${enterpriseInstanceUrl}/api/v3/user`
|
||||
: undefined;
|
||||
const callbackUrl =
|
||||
customCallbackUrl ||
|
||||
`${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
||||
/**
|
||||
* Configure sign-in for this provider, without it the provider can not be used to sign users in.
|
||||
*/
|
||||
signIn?: {
|
||||
/**
|
||||
* Maps an auth result to a Backstage identity for the user.
|
||||
*/
|
||||
resolver: SignInResolver<GithubOAuthResult>;
|
||||
};
|
||||
|
||||
const authHandler: AuthHandler<GithubOAuthResult> = options?.authHandler
|
||||
? options.authHandler
|
||||
: async ({ fullProfile }) => ({
|
||||
profile: makeProfileInfo(fullProfile),
|
||||
/**
|
||||
* The state encoder used to encode the 'state' parameter on the OAuth request.
|
||||
*
|
||||
* It should return a string that takes the state params (from the request), url encodes the params
|
||||
* and finally base64 encodes them.
|
||||
*
|
||||
* Providing your own stateEncoder will allow you to add addition parameters to the state field.
|
||||
*
|
||||
* It is typed as follows:
|
||||
* `export type StateEncoder = (input: OAuthState) => Promise<{encodedState: string}>;`
|
||||
*
|
||||
* Note: the stateEncoder must encode a 'nonce' value and an 'env' value. Without this, the OAuth flow will fail
|
||||
* (These two values will be set by the req.state by default)
|
||||
*
|
||||
* For more information, please see the helper module in ../../oauth/helpers #readState
|
||||
*/
|
||||
stateEncoder?: StateEncoder;
|
||||
}) {
|
||||
return ({ providerId, globalConfig, config, resolverContext }) =>
|
||||
OAuthEnvironmentHandler.mapConfig(config, envConfig => {
|
||||
const clientId = envConfig.getString('clientId');
|
||||
const clientSecret = envConfig.getString('clientSecret');
|
||||
const enterpriseInstanceUrl = envConfig
|
||||
.getOptionalString('enterpriseInstanceUrl')
|
||||
?.replace(/\/$/, '');
|
||||
const customCallbackUrl = envConfig.getOptionalString('callbackUrl');
|
||||
const authorizationUrl = enterpriseInstanceUrl
|
||||
? `${enterpriseInstanceUrl}/login/oauth/authorize`
|
||||
: undefined;
|
||||
const tokenUrl = enterpriseInstanceUrl
|
||||
? `${enterpriseInstanceUrl}/login/oauth/access_token`
|
||||
: undefined;
|
||||
const userProfileUrl = enterpriseInstanceUrl
|
||||
? `${enterpriseInstanceUrl}/api/v3/user`
|
||||
: undefined;
|
||||
const callbackUrl =
|
||||
customCallbackUrl ||
|
||||
`${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
||||
|
||||
const authHandler: AuthHandler<GithubOAuthResult> = options?.authHandler
|
||||
? options.authHandler
|
||||
: async ({ fullProfile }) => ({
|
||||
profile: makeProfileInfo(fullProfile),
|
||||
});
|
||||
|
||||
const stateEncoder: StateEncoder =
|
||||
options?.stateEncoder ??
|
||||
(async (
|
||||
req: OAuthStartRequest,
|
||||
): Promise<{ encodedState: string }> => {
|
||||
return { encodedState: encodeState(req.state) };
|
||||
});
|
||||
|
||||
const stateEncoder: StateEncoder =
|
||||
options?.stateEncoder ??
|
||||
(async (req: OAuthStartRequest): Promise<{ encodedState: string }> => {
|
||||
return { encodedState: encodeState(req.state) };
|
||||
const provider = new GithubAuthProvider({
|
||||
clientId,
|
||||
clientSecret,
|
||||
callbackUrl,
|
||||
tokenUrl,
|
||||
userProfileUrl,
|
||||
authorizationUrl,
|
||||
signInResolver: options?.signIn?.resolver,
|
||||
authHandler,
|
||||
stateEncoder,
|
||||
resolverContext,
|
||||
});
|
||||
|
||||
const provider = new GithubAuthProvider({
|
||||
clientId,
|
||||
clientSecret,
|
||||
callbackUrl,
|
||||
tokenUrl,
|
||||
userProfileUrl,
|
||||
authorizationUrl,
|
||||
signInResolver: options?.signIn?.resolver,
|
||||
authHandler,
|
||||
stateEncoder,
|
||||
resolverContext,
|
||||
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
||||
persistScopes: true,
|
||||
providerId,
|
||||
callbackUrl,
|
||||
});
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
||||
persistScopes: true,
|
||||
providerId,
|
||||
callbackUrl,
|
||||
});
|
||||
});
|
||||
};
|
||||
/**
|
||||
* @public
|
||||
* @deprecated Use `providers.github.create` instead
|
||||
*/
|
||||
export const createGithubProvider = github.create;
|
||||
|
||||
@@ -26,7 +26,6 @@ import {
|
||||
} from '../../lib/passport';
|
||||
import {
|
||||
RedirectInfo,
|
||||
AuthProviderFactory,
|
||||
SignInResolver,
|
||||
AuthHandler,
|
||||
AuthResolverContext,
|
||||
@@ -42,6 +41,7 @@ import {
|
||||
encodeState,
|
||||
OAuthResult,
|
||||
} from '../../lib/oauth';
|
||||
import { createAuthProviderIntegration } from '../createAuthProviderIntegration';
|
||||
|
||||
type PrivateInfo = {
|
||||
refreshToken: string;
|
||||
@@ -202,54 +202,67 @@ export type GitlabProviderOptions = {
|
||||
};
|
||||
};
|
||||
|
||||
export const createGitlabProvider = (options?: {
|
||||
/**
|
||||
* The profile transformation function used to verify and convert the auth response
|
||||
* into the profile that will be presented to the user.
|
||||
*/
|
||||
authHandler?: AuthHandler<OAuthResult>;
|
||||
/**
|
||||
* Auth provider integration for GitLab auth
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const gitlab = createAuthProviderIntegration({
|
||||
create(options?: {
|
||||
/**
|
||||
* The profile transformation function used to verify and convert the auth response
|
||||
* into the profile that will be presented to the user.
|
||||
*/
|
||||
authHandler?: AuthHandler<OAuthResult>;
|
||||
|
||||
/**
|
||||
* Configure sign-in for this provider, without it the provider can not be used to sign users in.
|
||||
*/
|
||||
/**
|
||||
* Maps an auth result to a Backstage identity for the user.
|
||||
*
|
||||
* Set to `'email'` to use the default email-based sign in resolver, which will search
|
||||
* the catalog for a single user entity that has a matching `microsoft.com/email` annotation.
|
||||
*/
|
||||
signIn?: {
|
||||
resolver: SignInResolver<OAuthResult>;
|
||||
};
|
||||
}): AuthProviderFactory => {
|
||||
return ({ providerId, globalConfig, config, resolverContext }) =>
|
||||
OAuthEnvironmentHandler.mapConfig(config, envConfig => {
|
||||
const clientId = envConfig.getString('clientId');
|
||||
const clientSecret = envConfig.getString('clientSecret');
|
||||
const audience = envConfig.getOptionalString('audience');
|
||||
const baseUrl = audience || 'https://gitlab.com';
|
||||
const customCallbackUrl = envConfig.getOptionalString('callbackUrl');
|
||||
const callbackUrl =
|
||||
customCallbackUrl ||
|
||||
`${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
||||
/**
|
||||
* Configure sign-in for this provider, without it the provider can not be used to sign users in.
|
||||
*/
|
||||
/**
|
||||
* Maps an auth result to a Backstage identity for the user.
|
||||
*
|
||||
* Set to `'email'` to use the default email-based sign in resolver, which will search
|
||||
* the catalog for a single user entity that has a matching `microsoft.com/email` annotation.
|
||||
*/
|
||||
signIn?: {
|
||||
resolver: SignInResolver<OAuthResult>;
|
||||
};
|
||||
}) {
|
||||
return ({ providerId, globalConfig, config, resolverContext }) =>
|
||||
OAuthEnvironmentHandler.mapConfig(config, envConfig => {
|
||||
const clientId = envConfig.getString('clientId');
|
||||
const clientSecret = envConfig.getString('clientSecret');
|
||||
const audience = envConfig.getOptionalString('audience');
|
||||
const baseUrl = audience || 'https://gitlab.com';
|
||||
const customCallbackUrl = envConfig.getOptionalString('callbackUrl');
|
||||
const callbackUrl =
|
||||
customCallbackUrl ||
|
||||
`${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
||||
|
||||
const authHandler: AuthHandler<OAuthResult> =
|
||||
options?.authHandler ?? gitlabDefaultAuthHandler;
|
||||
const authHandler: AuthHandler<OAuthResult> =
|
||||
options?.authHandler ?? gitlabDefaultAuthHandler;
|
||||
|
||||
const provider = new GitlabAuthProvider({
|
||||
clientId,
|
||||
clientSecret,
|
||||
callbackUrl,
|
||||
baseUrl,
|
||||
authHandler,
|
||||
signInResolver: options?.signIn?.resolver,
|
||||
resolverContext,
|
||||
const provider = new GitlabAuthProvider({
|
||||
clientId,
|
||||
clientSecret,
|
||||
callbackUrl,
|
||||
baseUrl,
|
||||
authHandler,
|
||||
signInResolver: options?.signIn?.resolver,
|
||||
resolverContext,
|
||||
});
|
||||
|
||||
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
||||
disableRefresh: false,
|
||||
providerId,
|
||||
callbackUrl,
|
||||
});
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
||||
disableRefresh: false,
|
||||
providerId,
|
||||
callbackUrl,
|
||||
});
|
||||
});
|
||||
};
|
||||
/**
|
||||
* @public
|
||||
* @deprecated Use `providers.gitlab.create` instead
|
||||
*/
|
||||
export const createGitlabProvider = gitlab.create;
|
||||
|
||||
@@ -37,12 +37,12 @@ import {
|
||||
PassportDoneCallback,
|
||||
} from '../../lib/passport';
|
||||
import {
|
||||
AuthProviderFactory,
|
||||
AuthHandler,
|
||||
RedirectInfo,
|
||||
SignInResolver,
|
||||
AuthResolverContext,
|
||||
} from '../types';
|
||||
import { createAuthProviderIntegration } from '../createAuthProviderIntegration';
|
||||
import { Logger } from 'winston';
|
||||
import fetch from 'node-fetch';
|
||||
|
||||
@@ -224,58 +224,71 @@ export type MicrosoftProviderOptions = {
|
||||
};
|
||||
};
|
||||
|
||||
export const createMicrosoftProvider = (options?: {
|
||||
/**
|
||||
* The profile transformation function used to verify and convert the auth response
|
||||
* into the profile that will be presented to the user.
|
||||
*/
|
||||
authHandler?: AuthHandler<OAuthResult>;
|
||||
|
||||
/**
|
||||
* Configure sign-in for this provider, without it the provider can not be used to sign users in.
|
||||
*/
|
||||
signIn?: {
|
||||
/**
|
||||
* Auth provider integration for Microsoft auth
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const microsoft = createAuthProviderIntegration({
|
||||
create(options?: {
|
||||
/**
|
||||
* Maps an auth result to a Backstage identity for the user.
|
||||
* The profile transformation function used to verify and convert the auth response
|
||||
* into the profile that will be presented to the user.
|
||||
*/
|
||||
resolver: SignInResolver<OAuthResult>;
|
||||
};
|
||||
}): AuthProviderFactory => {
|
||||
return ({ providerId, globalConfig, config, logger, resolverContext }) =>
|
||||
OAuthEnvironmentHandler.mapConfig(config, envConfig => {
|
||||
const clientId = envConfig.getString('clientId');
|
||||
const clientSecret = envConfig.getString('clientSecret');
|
||||
const tenantId = envConfig.getString('tenantId');
|
||||
authHandler?: AuthHandler<OAuthResult>;
|
||||
|
||||
const customCallbackUrl = envConfig.getOptionalString('callbackUrl');
|
||||
const callbackUrl =
|
||||
customCallbackUrl ||
|
||||
`${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
||||
const authorizationUrl = `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/authorize`;
|
||||
const tokenUrl = `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`;
|
||||
/**
|
||||
* Configure sign-in for this provider, without it the provider can not be used to sign users in.
|
||||
*/
|
||||
signIn?: {
|
||||
/**
|
||||
* Maps an auth result to a Backstage identity for the user.
|
||||
*/
|
||||
resolver: SignInResolver<OAuthResult>;
|
||||
};
|
||||
}) {
|
||||
return ({ providerId, globalConfig, config, logger, resolverContext }) =>
|
||||
OAuthEnvironmentHandler.mapConfig(config, envConfig => {
|
||||
const clientId = envConfig.getString('clientId');
|
||||
const clientSecret = envConfig.getString('clientSecret');
|
||||
const tenantId = envConfig.getString('tenantId');
|
||||
|
||||
const authHandler: AuthHandler<OAuthResult> = options?.authHandler
|
||||
? options.authHandler
|
||||
: async ({ fullProfile, params }) => ({
|
||||
profile: makeProfileInfo(fullProfile, params.id_token),
|
||||
});
|
||||
const customCallbackUrl = envConfig.getOptionalString('callbackUrl');
|
||||
const callbackUrl =
|
||||
customCallbackUrl ||
|
||||
`${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
||||
const authorizationUrl = `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/authorize`;
|
||||
const tokenUrl = `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`;
|
||||
|
||||
const provider = new MicrosoftAuthProvider({
|
||||
clientId,
|
||||
clientSecret,
|
||||
callbackUrl,
|
||||
authorizationUrl,
|
||||
tokenUrl,
|
||||
authHandler,
|
||||
signInResolver: options?.signIn?.resolver,
|
||||
logger,
|
||||
resolverContext,
|
||||
const authHandler: AuthHandler<OAuthResult> = options?.authHandler
|
||||
? options.authHandler
|
||||
: async ({ fullProfile, params }) => ({
|
||||
profile: makeProfileInfo(fullProfile, params.id_token),
|
||||
});
|
||||
|
||||
const provider = new MicrosoftAuthProvider({
|
||||
clientId,
|
||||
clientSecret,
|
||||
callbackUrl,
|
||||
authorizationUrl,
|
||||
tokenUrl,
|
||||
authHandler,
|
||||
signInResolver: options?.signIn?.resolver,
|
||||
logger,
|
||||
resolverContext,
|
||||
});
|
||||
|
||||
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
||||
disableRefresh: false,
|
||||
providerId,
|
||||
callbackUrl,
|
||||
});
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
||||
disableRefresh: false,
|
||||
providerId,
|
||||
callbackUrl,
|
||||
});
|
||||
});
|
||||
};
|
||||
/**
|
||||
* @public
|
||||
* @deprecated Use `providers.microsoft.create` instead
|
||||
*/
|
||||
export const createMicrosoftProvider = microsoft.create;
|
||||
|
||||
@@ -20,13 +20,13 @@ import { getBearerTokenFromAuthorizationHeader } from '@backstage/plugin-auth-no
|
||||
import {
|
||||
AuthHandler,
|
||||
SignInResolver,
|
||||
AuthProviderFactory,
|
||||
AuthProviderRouteHandlers,
|
||||
AuthResponse,
|
||||
AuthResolverContext,
|
||||
} from '../types';
|
||||
import { JWT } from 'jose';
|
||||
import { prepareBackstageIdentityResponse } from '../prepareBackstageIdentityResponse';
|
||||
import { createAuthProviderIntegration } from '../createAuthProviderIntegration';
|
||||
|
||||
export const OAUTH2_PROXY_JWT_HEADER = 'X-OAUTH2-PROXY-ID-TOKEN';
|
||||
|
||||
@@ -151,12 +151,12 @@ export class Oauth2ProxyAuthProvider<JWTPayload>
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory function for oauth2-proxy auth provider
|
||||
* Auth provider integration for oauth2-proxy auth
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const createOauth2ProxyProvider =
|
||||
<JWTPayload>(options: {
|
||||
export const oauth2Proxy = createAuthProviderIntegration({
|
||||
create<JWTPayload>(options: {
|
||||
/**
|
||||
* Configure an auth handler to generate a profile for the user.
|
||||
*/
|
||||
@@ -171,13 +171,21 @@ export const createOauth2ProxyProvider =
|
||||
*/
|
||||
resolver: SignInResolver<OAuth2ProxyResult<JWTPayload>>;
|
||||
};
|
||||
}): AuthProviderFactory =>
|
||||
({ resolverContext }) => {
|
||||
const signInResolver = options.signIn.resolver;
|
||||
const authHandler = options.authHandler;
|
||||
return new Oauth2ProxyAuthProvider<JWTPayload>({
|
||||
resolverContext,
|
||||
signInResolver,
|
||||
authHandler,
|
||||
});
|
||||
};
|
||||
}) {
|
||||
return ({ resolverContext }) => {
|
||||
const signInResolver = options.signIn.resolver;
|
||||
const authHandler = options.authHandler;
|
||||
return new Oauth2ProxyAuthProvider<JWTPayload>({
|
||||
resolverContext,
|
||||
signInResolver,
|
||||
authHandler,
|
||||
});
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* @public
|
||||
* @deprecated Use `providers.oauth2Proxy.create` instead
|
||||
*/
|
||||
export const createOauth2ProxyProvider = oauth2Proxy.create;
|
||||
|
||||
@@ -38,11 +38,11 @@ import {
|
||||
} from '../../lib/passport';
|
||||
import {
|
||||
AuthHandler,
|
||||
AuthProviderFactory,
|
||||
AuthResolverContext,
|
||||
RedirectInfo,
|
||||
SignInResolver,
|
||||
} from '../types';
|
||||
import { createAuthProviderIntegration } from '../createAuthProviderIntegration';
|
||||
|
||||
type PrivateInfo = {
|
||||
refreshToken: string;
|
||||
@@ -196,51 +196,65 @@ export type OAuth2ProviderOptions = {
|
||||
};
|
||||
};
|
||||
|
||||
export const createOAuth2Provider = (options?: {
|
||||
authHandler?: AuthHandler<OAuthResult>;
|
||||
/**
|
||||
* Auth provider integration for generic OAuth2 auth
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const oauth2 = createAuthProviderIntegration({
|
||||
create(options?: {
|
||||
authHandler?: AuthHandler<OAuthResult>;
|
||||
|
||||
signIn?: {
|
||||
resolver: SignInResolver<OAuthResult>;
|
||||
};
|
||||
}): AuthProviderFactory => {
|
||||
return ({ providerId, globalConfig, config, resolverContext }) =>
|
||||
OAuthEnvironmentHandler.mapConfig(config, envConfig => {
|
||||
const clientId = envConfig.getString('clientId');
|
||||
const clientSecret = envConfig.getString('clientSecret');
|
||||
const customCallbackUrl = envConfig.getOptionalString('callbackUrl');
|
||||
const callbackUrl =
|
||||
customCallbackUrl ||
|
||||
`${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
||||
const authorizationUrl = envConfig.getString('authorizationUrl');
|
||||
const tokenUrl = envConfig.getString('tokenUrl');
|
||||
const scope = envConfig.getOptionalString('scope');
|
||||
const includeBasicAuth = envConfig.getOptionalBoolean('includeBasicAuth');
|
||||
const disableRefresh =
|
||||
envConfig.getOptionalBoolean('disableRefresh') ?? false;
|
||||
signIn?: {
|
||||
resolver: SignInResolver<OAuthResult>;
|
||||
};
|
||||
}) {
|
||||
return ({ providerId, globalConfig, config, resolverContext }) =>
|
||||
OAuthEnvironmentHandler.mapConfig(config, envConfig => {
|
||||
const clientId = envConfig.getString('clientId');
|
||||
const clientSecret = envConfig.getString('clientSecret');
|
||||
const customCallbackUrl = envConfig.getOptionalString('callbackUrl');
|
||||
const callbackUrl =
|
||||
customCallbackUrl ||
|
||||
`${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
||||
const authorizationUrl = envConfig.getString('authorizationUrl');
|
||||
const tokenUrl = envConfig.getString('tokenUrl');
|
||||
const scope = envConfig.getOptionalString('scope');
|
||||
const includeBasicAuth =
|
||||
envConfig.getOptionalBoolean('includeBasicAuth');
|
||||
const disableRefresh =
|
||||
envConfig.getOptionalBoolean('disableRefresh') ?? false;
|
||||
|
||||
const authHandler: AuthHandler<OAuthResult> = options?.authHandler
|
||||
? options.authHandler
|
||||
: async ({ fullProfile, params }) => ({
|
||||
profile: makeProfileInfo(fullProfile, params.id_token),
|
||||
});
|
||||
const authHandler: AuthHandler<OAuthResult> = options?.authHandler
|
||||
? options.authHandler
|
||||
: async ({ fullProfile, params }) => ({
|
||||
profile: makeProfileInfo(fullProfile, params.id_token),
|
||||
});
|
||||
|
||||
const provider = new OAuth2AuthProvider({
|
||||
clientId,
|
||||
clientSecret,
|
||||
callbackUrl,
|
||||
signInResolver: options?.signIn?.resolver,
|
||||
authHandler,
|
||||
authorizationUrl,
|
||||
tokenUrl,
|
||||
scope,
|
||||
includeBasicAuth,
|
||||
resolverContext,
|
||||
const provider = new OAuth2AuthProvider({
|
||||
clientId,
|
||||
clientSecret,
|
||||
callbackUrl,
|
||||
signInResolver: options?.signIn?.resolver,
|
||||
authHandler,
|
||||
authorizationUrl,
|
||||
tokenUrl,
|
||||
scope,
|
||||
includeBasicAuth,
|
||||
resolverContext,
|
||||
});
|
||||
|
||||
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
||||
disableRefresh,
|
||||
providerId,
|
||||
callbackUrl,
|
||||
});
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
||||
disableRefresh,
|
||||
providerId,
|
||||
callbackUrl,
|
||||
});
|
||||
});
|
||||
};
|
||||
/**
|
||||
* @public
|
||||
* @deprecated Use `providers.oauth2.create` instead
|
||||
*/
|
||||
export const createOAuth2Provider = oauth2.create;
|
||||
|
||||
@@ -39,11 +39,11 @@ import {
|
||||
} from '../../lib/passport';
|
||||
import {
|
||||
AuthHandler,
|
||||
AuthProviderFactory,
|
||||
AuthResolverContext,
|
||||
RedirectInfo,
|
||||
SignInResolver,
|
||||
} from '../types';
|
||||
import { createAuthProviderIntegration } from '../createAuthProviderIntegration';
|
||||
|
||||
type PrivateInfo = {
|
||||
refreshToken?: string;
|
||||
@@ -209,55 +209,68 @@ export type OidcProviderOptions = {
|
||||
};
|
||||
};
|
||||
|
||||
export const createOidcProvider = (options?: {
|
||||
authHandler?: AuthHandler<OidcAuthResult>;
|
||||
/**
|
||||
* Auth provider integration for generic OpenID Connect auth
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const oidc = createAuthProviderIntegration({
|
||||
create(options?: {
|
||||
authHandler?: AuthHandler<OidcAuthResult>;
|
||||
|
||||
signIn?: {
|
||||
resolver: SignInResolver<OidcAuthResult>;
|
||||
};
|
||||
}): AuthProviderFactory => {
|
||||
return ({ providerId, globalConfig, config, resolverContext }) =>
|
||||
OAuthEnvironmentHandler.mapConfig(config, envConfig => {
|
||||
const clientId = envConfig.getString('clientId');
|
||||
const clientSecret = envConfig.getString('clientSecret');
|
||||
const customCallbackUrl = envConfig.getOptionalString('callbackUrl');
|
||||
const callbackUrl =
|
||||
customCallbackUrl ||
|
||||
`${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
||||
const metadataUrl = envConfig.getString('metadataUrl');
|
||||
const tokenSignedResponseAlg = envConfig.getOptionalString(
|
||||
'tokenSignedResponseAlg',
|
||||
);
|
||||
const scope = envConfig.getOptionalString('scope');
|
||||
const prompt = envConfig.getOptionalString('prompt');
|
||||
signIn?: {
|
||||
resolver: SignInResolver<OidcAuthResult>;
|
||||
};
|
||||
}) {
|
||||
return ({ providerId, globalConfig, config, resolverContext }) =>
|
||||
OAuthEnvironmentHandler.mapConfig(config, envConfig => {
|
||||
const clientId = envConfig.getString('clientId');
|
||||
const clientSecret = envConfig.getString('clientSecret');
|
||||
const customCallbackUrl = envConfig.getOptionalString('callbackUrl');
|
||||
const callbackUrl =
|
||||
customCallbackUrl ||
|
||||
`${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
||||
const metadataUrl = envConfig.getString('metadataUrl');
|
||||
const tokenSignedResponseAlg = envConfig.getOptionalString(
|
||||
'tokenSignedResponseAlg',
|
||||
);
|
||||
const scope = envConfig.getOptionalString('scope');
|
||||
const prompt = envConfig.getOptionalString('prompt');
|
||||
|
||||
const authHandler: AuthHandler<OidcAuthResult> = options?.authHandler
|
||||
? options.authHandler
|
||||
: async ({ userinfo }) => ({
|
||||
profile: {
|
||||
displayName: userinfo.name,
|
||||
email: userinfo.email,
|
||||
picture: userinfo.picture,
|
||||
},
|
||||
});
|
||||
const authHandler: AuthHandler<OidcAuthResult> = options?.authHandler
|
||||
? options.authHandler
|
||||
: async ({ userinfo }) => ({
|
||||
profile: {
|
||||
displayName: userinfo.name,
|
||||
email: userinfo.email,
|
||||
picture: userinfo.picture,
|
||||
},
|
||||
});
|
||||
|
||||
const provider = new OidcAuthProvider({
|
||||
clientId,
|
||||
clientSecret,
|
||||
callbackUrl,
|
||||
tokenSignedResponseAlg,
|
||||
metadataUrl,
|
||||
scope,
|
||||
prompt,
|
||||
signInResolver: options?.signIn?.resolver,
|
||||
authHandler,
|
||||
resolverContext,
|
||||
const provider = new OidcAuthProvider({
|
||||
clientId,
|
||||
clientSecret,
|
||||
callbackUrl,
|
||||
tokenSignedResponseAlg,
|
||||
metadataUrl,
|
||||
scope,
|
||||
prompt,
|
||||
signInResolver: options?.signIn?.resolver,
|
||||
authHandler,
|
||||
resolverContext,
|
||||
});
|
||||
|
||||
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
||||
disableRefresh: false,
|
||||
providerId,
|
||||
callbackUrl,
|
||||
});
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
||||
disableRefresh: false,
|
||||
providerId,
|
||||
callbackUrl,
|
||||
});
|
||||
});
|
||||
};
|
||||
/**
|
||||
* @public
|
||||
* @deprecated Use `providers.oidc.create` instead
|
||||
*/
|
||||
export const createOidcProvider = oidc.create;
|
||||
|
||||
@@ -37,12 +37,12 @@ import {
|
||||
PassportDoneCallback,
|
||||
} from '../../lib/passport';
|
||||
import {
|
||||
AuthProviderFactory,
|
||||
AuthHandler,
|
||||
RedirectInfo,
|
||||
SignInResolver,
|
||||
AuthResolverContext,
|
||||
} from '../types';
|
||||
import { createAuthProviderIntegration } from '../createAuthProviderIntegration';
|
||||
import { StateStore } from 'passport-oauth2';
|
||||
|
||||
type PrivateInfo = {
|
||||
@@ -226,60 +226,73 @@ export type OktaProviderOptions = {
|
||||
};
|
||||
};
|
||||
|
||||
export const createOktaProvider = (_options?: {
|
||||
/**
|
||||
* The profile transformation function used to verify and convert the auth response
|
||||
* into the profile that will be presented to the user.
|
||||
*/
|
||||
authHandler?: AuthHandler<OAuthResult>;
|
||||
|
||||
/**
|
||||
* Configure sign-in for this provider, without it the provider can not be used to sign users in.
|
||||
*/
|
||||
signIn?: {
|
||||
/**
|
||||
* Auth provider integration for Okta auth
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const okta = createAuthProviderIntegration({
|
||||
create(options?: {
|
||||
/**
|
||||
* Maps an auth result to a Backstage identity for the user.
|
||||
* The profile transformation function used to verify and convert the auth response
|
||||
* into the profile that will be presented to the user.
|
||||
*/
|
||||
resolver: SignInResolver<OAuthResult>;
|
||||
};
|
||||
}): AuthProviderFactory => {
|
||||
return ({ providerId, globalConfig, config, resolverContext }) =>
|
||||
OAuthEnvironmentHandler.mapConfig(config, envConfig => {
|
||||
const clientId = envConfig.getString('clientId');
|
||||
const clientSecret = envConfig.getString('clientSecret');
|
||||
const audience = envConfig.getString('audience');
|
||||
const customCallbackUrl = envConfig.getOptionalString('callbackUrl');
|
||||
const callbackUrl =
|
||||
customCallbackUrl ||
|
||||
`${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
||||
authHandler?: AuthHandler<OAuthResult>;
|
||||
|
||||
// This is a safe assumption as `passport-okta-oauth` uses the audience
|
||||
// as the base for building the authorization, token, and user info URLs.
|
||||
// https://github.com/fischerdan/passport-okta-oauth/blob/ea9ac42d/lib/passport-okta-oauth/oauth2.js#L12-L14
|
||||
if (!audience.startsWith('https://')) {
|
||||
throw new Error("URL for 'audience' must start with 'https://'.");
|
||||
}
|
||||
/**
|
||||
* Configure sign-in for this provider, without it the provider can not be used to sign users in.
|
||||
*/
|
||||
signIn?: {
|
||||
/**
|
||||
* Maps an auth result to a Backstage identity for the user.
|
||||
*/
|
||||
resolver: SignInResolver<OAuthResult>;
|
||||
};
|
||||
}) {
|
||||
return ({ providerId, globalConfig, config, resolverContext }) =>
|
||||
OAuthEnvironmentHandler.mapConfig(config, envConfig => {
|
||||
const clientId = envConfig.getString('clientId');
|
||||
const clientSecret = envConfig.getString('clientSecret');
|
||||
const audience = envConfig.getString('audience');
|
||||
const customCallbackUrl = envConfig.getOptionalString('callbackUrl');
|
||||
const callbackUrl =
|
||||
customCallbackUrl ||
|
||||
`${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
||||
|
||||
const authHandler: AuthHandler<OAuthResult> = _options?.authHandler
|
||||
? _options.authHandler
|
||||
: async ({ fullProfile, params }) => ({
|
||||
profile: makeProfileInfo(fullProfile, params.id_token),
|
||||
});
|
||||
// This is a safe assumption as `passport-okta-oauth` uses the audience
|
||||
// as the base for building the authorization, token, and user info URLs.
|
||||
// https://github.com/fischerdan/passport-okta-oauth/blob/ea9ac42d/lib/passport-okta-oauth/oauth2.js#L12-L14
|
||||
if (!audience.startsWith('https://')) {
|
||||
throw new Error("URL for 'audience' must start with 'https://'.");
|
||||
}
|
||||
|
||||
const provider = new OktaAuthProvider({
|
||||
audience,
|
||||
clientId,
|
||||
clientSecret,
|
||||
callbackUrl,
|
||||
authHandler,
|
||||
signInResolver: _options?.signIn?.resolver,
|
||||
resolverContext,
|
||||
const authHandler: AuthHandler<OAuthResult> = options?.authHandler
|
||||
? options.authHandler
|
||||
: async ({ fullProfile, params }) => ({
|
||||
profile: makeProfileInfo(fullProfile, params.id_token),
|
||||
});
|
||||
|
||||
const provider = new OktaAuthProvider({
|
||||
audience,
|
||||
clientId,
|
||||
clientSecret,
|
||||
callbackUrl,
|
||||
authHandler,
|
||||
signInResolver: options?.signIn?.resolver,
|
||||
resolverContext,
|
||||
});
|
||||
|
||||
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
||||
disableRefresh: false,
|
||||
providerId,
|
||||
callbackUrl,
|
||||
});
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
||||
disableRefresh: false,
|
||||
providerId,
|
||||
callbackUrl,
|
||||
});
|
||||
});
|
||||
};
|
||||
/**
|
||||
* @public
|
||||
* @deprecated Use `providers.okta.create` instead
|
||||
*/
|
||||
export const createOktaProvider = okta.create;
|
||||
|
||||
@@ -38,11 +38,11 @@ import {
|
||||
} from '../../lib/passport';
|
||||
import {
|
||||
RedirectInfo,
|
||||
AuthProviderFactory,
|
||||
AuthHandler,
|
||||
SignInResolver,
|
||||
AuthResolverContext,
|
||||
} from '../types';
|
||||
import { createAuthProviderIntegration } from '../createAuthProviderIntegration';
|
||||
|
||||
type PrivateInfo = {
|
||||
refreshToken: string;
|
||||
@@ -187,54 +187,66 @@ export type OneLoginProviderOptions = {
|
||||
};
|
||||
};
|
||||
|
||||
/** @public */
|
||||
export const createOneLoginProvider = (options?: {
|
||||
/**
|
||||
* The profile transformation function used to verify and convert the auth response
|
||||
* into the profile that will be presented to the user.
|
||||
*/
|
||||
authHandler?: AuthHandler<OAuthResult>;
|
||||
|
||||
/**
|
||||
* Configure sign-in for this provider, without it the provider can not be used to sign users in.
|
||||
*/
|
||||
signIn?: {
|
||||
/**
|
||||
* Auth provider integration for OneLogin auth
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const onelogin = createAuthProviderIntegration({
|
||||
create(options?: {
|
||||
/**
|
||||
* Maps an auth result to a Backstage identity for the user.
|
||||
* The profile transformation function used to verify and convert the auth response
|
||||
* into the profile that will be presented to the user.
|
||||
*/
|
||||
resolver: SignInResolver<OAuthResult>;
|
||||
};
|
||||
}): AuthProviderFactory => {
|
||||
return ({ providerId, globalConfig, config, resolverContext }) =>
|
||||
OAuthEnvironmentHandler.mapConfig(config, envConfig => {
|
||||
const clientId = envConfig.getString('clientId');
|
||||
const clientSecret = envConfig.getString('clientSecret');
|
||||
const issuer = envConfig.getString('issuer');
|
||||
const customCallbackUrl = envConfig.getOptionalString('callbackUrl');
|
||||
const callbackUrl =
|
||||
customCallbackUrl ||
|
||||
`${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
||||
authHandler?: AuthHandler<OAuthResult>;
|
||||
|
||||
const authHandler: AuthHandler<OAuthResult> = options?.authHandler
|
||||
? options.authHandler
|
||||
: async ({ fullProfile, params }) => ({
|
||||
profile: makeProfileInfo(fullProfile, params.id_token),
|
||||
});
|
||||
/**
|
||||
* Configure sign-in for this provider, without it the provider can not be used to sign users in.
|
||||
*/
|
||||
signIn?: {
|
||||
/**
|
||||
* Maps an auth result to a Backstage identity for the user.
|
||||
*/
|
||||
resolver: SignInResolver<OAuthResult>;
|
||||
};
|
||||
}) {
|
||||
return ({ providerId, globalConfig, config, resolverContext }) =>
|
||||
OAuthEnvironmentHandler.mapConfig(config, envConfig => {
|
||||
const clientId = envConfig.getString('clientId');
|
||||
const clientSecret = envConfig.getString('clientSecret');
|
||||
const issuer = envConfig.getString('issuer');
|
||||
const customCallbackUrl = envConfig.getOptionalString('callbackUrl');
|
||||
const callbackUrl =
|
||||
customCallbackUrl ||
|
||||
`${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
||||
|
||||
const provider = new OneLoginProvider({
|
||||
clientId,
|
||||
clientSecret,
|
||||
callbackUrl,
|
||||
issuer,
|
||||
authHandler,
|
||||
signInResolver: options?.signIn?.resolver,
|
||||
resolverContext,
|
||||
const authHandler: AuthHandler<OAuthResult> = options?.authHandler
|
||||
? options.authHandler
|
||||
: async ({ fullProfile, params }) => ({
|
||||
profile: makeProfileInfo(fullProfile, params.id_token),
|
||||
});
|
||||
|
||||
const provider = new OneLoginProvider({
|
||||
clientId,
|
||||
clientSecret,
|
||||
callbackUrl,
|
||||
issuer,
|
||||
authHandler,
|
||||
signInResolver: options?.signIn?.resolver,
|
||||
resolverContext,
|
||||
});
|
||||
|
||||
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
||||
disableRefresh: false,
|
||||
providerId,
|
||||
callbackUrl,
|
||||
});
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
||||
disableRefresh: false,
|
||||
providerId,
|
||||
callbackUrl,
|
||||
});
|
||||
});
|
||||
};
|
||||
/**
|
||||
* @public
|
||||
* @deprecated Use `providers.onelogin.create` instead
|
||||
*/
|
||||
export const createOneLoginProvider = onelogin.create;
|
||||
|
||||
@@ -28,13 +28,13 @@ import {
|
||||
} from '../../lib/passport';
|
||||
import {
|
||||
AuthProviderRouteHandlers,
|
||||
AuthProviderFactory,
|
||||
AuthHandler,
|
||||
SignInResolver,
|
||||
AuthResponse,
|
||||
AuthResolverContext,
|
||||
} from '../types';
|
||||
import { postMessageResponse } from '../../lib/flow';
|
||||
import { createAuthProviderIntegration } from '../createAuthProviderIntegration';
|
||||
import { AuthenticationError, isError } from '@backstage/errors';
|
||||
import { prepareBackstageIdentityResponse } from '../prepareBackstageIdentityResponse';
|
||||
|
||||
@@ -167,55 +167,67 @@ export type SamlProviderOptions = {
|
||||
};
|
||||
};
|
||||
|
||||
/** @public */
|
||||
export const createSamlProvider = (options?: {
|
||||
/**
|
||||
* The profile transformation function used to verify and convert the auth response
|
||||
* into the profile that will be presented to the user.
|
||||
*/
|
||||
authHandler?: AuthHandler<SamlAuthResult>;
|
||||
|
||||
/**
|
||||
* Configure sign-in for this provider, without it the provider can not be used to sign users in.
|
||||
*/
|
||||
signIn?: {
|
||||
/**
|
||||
* Auth provider integration for SAML auth
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const saml = createAuthProviderIntegration({
|
||||
create(options?: {
|
||||
/**
|
||||
* Maps an auth result to a Backstage identity for the user.
|
||||
* The profile transformation function used to verify and convert the auth response
|
||||
* into the profile that will be presented to the user.
|
||||
*/
|
||||
resolver: SignInResolver<SamlAuthResult>;
|
||||
};
|
||||
}): AuthProviderFactory => {
|
||||
return ({ providerId, globalConfig, config, resolverContext }) => {
|
||||
const authHandler: AuthHandler<SamlAuthResult> = options?.authHandler
|
||||
? options.authHandler
|
||||
: async ({ fullProfile }) => ({
|
||||
profile: {
|
||||
email: fullProfile.email,
|
||||
displayName: fullProfile.displayName,
|
||||
},
|
||||
});
|
||||
authHandler?: AuthHandler<SamlAuthResult>;
|
||||
|
||||
return new SamlAuthProvider({
|
||||
callbackUrl: `${globalConfig.baseUrl}/${providerId}/handler/frame`,
|
||||
entryPoint: config.getString('entryPoint'),
|
||||
logoutUrl: config.getOptionalString('logoutUrl'),
|
||||
audience: config.getOptionalString('audience'),
|
||||
issuer: config.getString('issuer'),
|
||||
cert: config.getString('cert'),
|
||||
privateKey: config.getOptionalString('privateKey'),
|
||||
authnContext: config.getOptionalStringArray('authnContext'),
|
||||
identifierFormat: config.getOptionalString('identifierFormat'),
|
||||
decryptionPvk: config.getOptionalString('decryptionPvk'),
|
||||
signatureAlgorithm: config.getOptionalString('signatureAlgorithm') as
|
||||
| SignatureAlgorithm
|
||||
| undefined,
|
||||
digestAlgorithm: config.getOptionalString('digestAlgorithm'),
|
||||
acceptedClockSkewMs: config.getOptionalNumber('acceptedClockSkewMs'),
|
||||
/**
|
||||
* Configure sign-in for this provider, without it the provider can not be used to sign users in.
|
||||
*/
|
||||
signIn?: {
|
||||
/**
|
||||
* Maps an auth result to a Backstage identity for the user.
|
||||
*/
|
||||
resolver: SignInResolver<SamlAuthResult>;
|
||||
};
|
||||
}) {
|
||||
return ({ providerId, globalConfig, config, resolverContext }) => {
|
||||
const authHandler: AuthHandler<SamlAuthResult> = options?.authHandler
|
||||
? options.authHandler
|
||||
: async ({ fullProfile }) => ({
|
||||
profile: {
|
||||
email: fullProfile.email,
|
||||
displayName: fullProfile.displayName,
|
||||
},
|
||||
});
|
||||
|
||||
appUrl: globalConfig.appUrl,
|
||||
authHandler,
|
||||
signInResolver: options?.signIn?.resolver,
|
||||
resolverContext,
|
||||
});
|
||||
};
|
||||
};
|
||||
return new SamlAuthProvider({
|
||||
callbackUrl: `${globalConfig.baseUrl}/${providerId}/handler/frame`,
|
||||
entryPoint: config.getString('entryPoint'),
|
||||
logoutUrl: config.getOptionalString('logoutUrl'),
|
||||
audience: config.getOptionalString('audience'),
|
||||
issuer: config.getString('issuer'),
|
||||
cert: config.getString('cert'),
|
||||
privateKey: config.getOptionalString('privateKey'),
|
||||
authnContext: config.getOptionalStringArray('authnContext'),
|
||||
identifierFormat: config.getOptionalString('identifierFormat'),
|
||||
decryptionPvk: config.getOptionalString('decryptionPvk'),
|
||||
signatureAlgorithm: config.getOptionalString('signatureAlgorithm') as
|
||||
| SignatureAlgorithm
|
||||
| undefined,
|
||||
digestAlgorithm: config.getOptionalString('digestAlgorithm'),
|
||||
acceptedClockSkewMs: config.getOptionalNumber('acceptedClockSkewMs'),
|
||||
|
||||
appUrl: globalConfig.appUrl,
|
||||
authHandler,
|
||||
signInResolver: options?.signIn?.resolver,
|
||||
resolverContext,
|
||||
});
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* @public
|
||||
* @deprecated Use `providers.saml.create` instead
|
||||
*/
|
||||
export const createSamlProvider = saml.create;
|
||||
|
||||
Reference in New Issue
Block a user