Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion docs/auth.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,14 +130,31 @@ For more information on setting up the OIDC auth provider, consult the [Backstag

### Sign In Page configuration value

After selecting the authentication provider you wish to use with your RHDH instance, ensure to add the `signInPage` configuration value to ensure that the frontend displays the appropriate authentication provider.
After selecting the authentication provider(s) you wish to use with your RHDH instance, ensure to add the `signInPage` configuration value to ensure that the frontend displays the appropriate authentication provider(s).

#### Single provider

- Add the corresponding Authentication provider key as the value to `signInPage` in your `app-config`. Where `provider-id` matches the chosen provider from the table above.

```yaml
signInPage: <provider-id>
```

#### Multiple providers

- To allow users to authenticate with multiple auth providers, you can specify a list of provider IDs:

```yaml
signInPage:
- github
- microsoft
- oidc
```

This will display a sign-in page with buttons for each of the specified authentication providers, allowing users to choose their preferred method of authentication.

**Note:** If any of the specified providers is a proxied provider (e.g., `oauth2Proxy`), only the first proxied provider will be used and a proxied sign-in page will be displayed instead.

### Enabling/Disabling the guest provider and login

The guest login is provided by a special authentication provider that must be explicitly enabled. This authentication provider should be used for development purposes only and is not intended for production, as it creates a default user that has user-level access to the Backstage instance.
Expand Down
2 changes: 1 addition & 1 deletion packages/app/config.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ export interface Config {
* The signInPage provider
* @visibility frontend
*/
signInPage?: string;
signInPage?: string | string[];
/**
* The option to includes transient parent groups when determining user group membership
* @visibility frontend
Expand Down
53 changes: 36 additions & 17 deletions packages/app/src/components/SignInPage/SignInPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -156,27 +156,46 @@ export function SignInPage(props: SignInPageProps): React.JSX.Element {
const configApi = useApi(configApiRef);
const { t } = useTranslation();
const isDevEnv = configApi.getString('auth.environment') === 'development';
const provider =
configApi.getOptionalString('signInPage') ?? DEFAULT_PROVIDER;

const providers = createProviders(t);
const providerConfig =
providers.get(provider) ?? providers.get(DEFAULT_PROVIDER)!;
const signInPageConfig = configApi.getOptional<string | string[]>(
'signInPage',
);
const configValue = signInPageConfig ?? DEFAULT_PROVIDER;
const providerNames = Array.isArray(configValue)
? configValue
: [configValue];

if (typeof providerConfig === 'object') {
const providerList = isDevEnv
? (['guest', providerConfig] satisfies ['guest', SignInProviderConfig])
: [providerConfig];
const providers = createProviders(t);

return (
<CCSignInPage
{...props}
title={t('signIn.page.title')}
align="center"
providers={providerList}
/>
const providerConfigs = providerNames
.map(name => providers.get(name))
.filter(
(config): config is SignInProviderConfig | string => config !== undefined,
);

if (providerConfigs.length === 0) {
const defaultProvider = providers.get(DEFAULT_PROVIDER);
if (defaultProvider) providerConfigs.push(defaultProvider);
}

return <ProxiedSignInPage {...props} provider={providerConfig} />;
// If any provider is proxied (i.e. does not use SignInProviderConfig), use the first proxied provider
if (providerConfigs.some(config => typeof config === 'string')) {
const proxiedProvider = providerConfigs.find(
config => typeof config === 'string',
) as string;
return <ProxiedSignInPage {...props} provider={proxiedProvider} />;
}

const providerList = isDevEnv
? ['guest' as const, ...(providerConfigs as SignInProviderConfig[])]
: (providerConfigs as SignInProviderConfig[]);

return (
<CCSignInPage
{...props}
title={t('signIn.page.title')}
align="center"
providers={providerList}
/>
);
}
Loading