Added backend install steps for various auth providers

Signed-off-by: Andre Wanlin <awanlin@spotify.com>
This commit is contained in:
Andre Wanlin
2024-07-05 12:07:22 -05:00
parent e43d17bea7
commit 0976bbd152
16 changed files with 439 additions and 551 deletions
+17
View File
@@ -79,6 +79,23 @@ The resolvers will be tried in order, but will only be skipped if they throw a `
If these resolvers do not fit your needs you can build a custom resolver, this is covered in the [Building Custom Resolvers](../identity-resolver.md#building-custom-resolvers) section of the Sign-in Identities and Resolvers documentation.
## Backend Installation
To add the provider to the backend we will first need to install the package by running this command:
```bash title="from your Backstage root directory"
yarn --cwd packages/backend add @backstage/plugin-auth-backend-module-atlassian-provider
```
Then we will need to this line:
```ts title="in packages/backend/src/index.ts"
backend.add(import('@backstage/plugin-auth-backend'));
/* highlight-add-start */
backend.add(import('@backstage/plugin-auth-backend-module-atlassian-provider'));
/* highlight-add-end */
```
## Adding the provider to the Backstage frontend
To add the provider to the frontend, add the `atlassianAuthApi` reference and
+36 -31
View File
@@ -8,37 +8,6 @@ description: Adding AWS ALB as an authentication provider in Backstage
Backstage can de deployed behind [AWS Application Load Balancer](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/introduction.html)
and get the user seamlessly authenticated.
## Installation
### Backend
:::note
These instructions are written for the [new backend system](../../backend-system/index.md).
:::
Add the `@backstage/plugin-auth-backend-module-aws-alb-provider` to your backend installation.
```sh
# From your Backstage root directory
yarn --cwd packages/backend add @backstage/plugin-auth-backend-module-aws-alb-provider
```
Then, add it to your backend's source,
```ts title="packages/backend/src/index.ts"
const backend = createBackend();
backend.add(import('@backstage/plugin-auth-backend'));
// highlight-add-next-line
backend.add(import('@backstage/plugin-auth-backend-module-aws-alb-provider'));
await backend.start();
```
### Frontend
See [Sign-In with Proxy Providers](../index.md#sign-in-with-proxy-providers) for pointers on how to set up the sign-in page, and to also make it work smoothly for local development.
## Configuration
The provider configuration can be added to your `app-config.yaml` under the root
@@ -57,4 +26,40 @@ auth:
- resolver: emailLocalPartMatchingUserEntityName
```
### Resolvers
This provider includes several resolvers out of the box that you can use:
- `emailMatchingUserEntityProfileEmail`: Matches the email address from the auth provider with the User entity that has a matching `spec.profile.email`. If no match is found it will throw a `NotFoundError`.
- `emailLocalPartMatchingUserEntityName`: Matches the [local part](https://en.wikipedia.org/wiki/Email_address#Local-part) of the email address from the auth provider with the User entity that has a matching `name`. If no match is found it will throw a `NotFoundError`.
:::note Note
The resolvers will be tried in order, but will only be skipped if they throw a `NotFoundError`.
:::
If these resolvers do not fit your needs you can build a custom resolver, this is covered in the [Building Custom Resolvers](../identity-resolver.md#building-custom-resolvers) section of the Sign-in Identities and Resolvers documentation.
## Backend Installation
To add the provider to the backend we will first need to install the package by running this command:
```bash title="from your Backstage root directory"
yarn --cwd packages/backend add @backstage/plugin-auth-backend-module-aws-alb-provider
```
Then we will need to add this line:
```ts title="in packages/backend/src/index.ts"
backend.add(import('@backstage/plugin-auth-backend'));
/* highlight-add-start */
backend.add(import('@backstage/plugin-auth-backend-module-aws-alb-provider'));
/* highlight-add-end */
```
## Adding the provider to the Backstage frontend
See [Sign-In with Proxy Providers](../index.md#sign-in-with-proxy-providers) for pointers on how to set up the sign-in page, and to also make it work smoothly for local development. You'll use `awsalb` as the provider name.
If you [provide a custom sign in resolver](https://backstage.io/docs/auth/identity-resolver#building-custom-resolvers), you can skip the `signIn` block entirely.
+41 -36
View File
@@ -37,6 +37,13 @@ auth:
development:
clientId: ${AUTH_BITBUCKET_CLIENT_ID}
clientSecret: ${AUTH_BITBUCKET_CLIENT_SECRET}
signIn:
resolvers:
# typically you would pick one of these
- resolver: emailMatchingUserEntityProfileEmail
- resolver: emailLocalPartMatchingUserEntityName
- resolver: userIdMatchingUserEntityAnnotation
- resolver: usernameMatchingUserEntityAnnotation
```
The Bitbucket provider is a structure with two configuration keys:
@@ -45,44 +52,42 @@ The Bitbucket provider is a structure with two configuration keys:
`b59241722e3c3b4816e2`
- `clientSecret`: The Secret tied to the generated Key.
### Resolvers
This provider includes several resolvers out of the box that you can use:
- `emailMatchingUserEntityProfileEmail`: Matches the email address from the auth provider with the User entity that has a matching `spec.profile.email`. If no match is found it will throw a `NotFoundError`.
- `emailLocalPartMatchingUserEntityName`: Matches the [local part](https://en.wikipedia.org/wiki/Email_address#Local-part) of the email address from the auth provider with the User entity that has a matching `name`. If no match is found it will throw a `NotFoundError`.
- `userIdMatchingUserEntityAnnotation`: Matches the `userId` from the auth provider with the User entity that has a matching `bitbucket.org/user-id` annotation. If no match is found it will throw a `NotFoundError`.
- `usernameMatchingUserEntityAnnotation`: Matches the `username` from the auth provider with the User entity that has a matching `bitbucket.org/username` annotation. If no match is found it will throw a `NotFoundError`.
:::note Note
The resolvers will be tried in order, but will only be skipped if they throw a `NotFoundError`.
:::
If these resolvers do not fit your needs you can build a custom resolver, this is covered in the [Building Custom Resolvers](../identity-resolver.md#building-custom-resolvers) section of the Sign-in Identities and Resolvers documentation.
## Backend Installation
To add the provider to the backend we will first need to install the package by running this command:
```bash title="from your Backstage root directory"
yarn --cwd packages/backend add @backstage/plugin-auth-backend-module-bitbucket-provider
```
Then we will need to add this line:
```ts title="in packages/backend/src/index.ts"
backend.add(import('@backstage/plugin-auth-backend'));
/* highlight-add-start */
backend.add(import('@backstage/plugin-auth-backend-module-bitbucket-provider'));
/* highlight-add-end */
```
## Adding the provider to the Backstage frontend
To add the provider to the frontend, add the `bitbucketAuthApi` reference and
`SignInPage` component as shown in
[Adding the provider to the sign-in page](../index.md#adding-the-provider-to-the-sign-in-page).
## Using Bitbucket for sign-in
In order to use the Bitbucket provider for sign-in, you must configure it with a
`signIn.resolver`. See the
[Sign-In Resolver documentation](../identity-resolver.md) for more details on
how this is done. Note that for the Bitbucket provider, you'll want to use
`bitbucket` as the provider ID, and `providers.bitbucket.create` for the provider
factory.
The `@backstage/plugin-auth-backend` plugin also comes with two built-in
resolvers that can be used if desired. The first one is the
`bitbucketUsernameSignInResolver`, which identifies users by matching their
Bitbucket username to `bitbucket.org/username` annotations of `User` entities in
the catalog. Note that you must populate your catalog with matching entities or
users will not be able to sign in.
The second resolver is the `bitbucketUserIdSignInResolver`, which works the
same way, but uses the Bitbucket user ID instead, and matches on the
`bitbucket.org/user-id` annotation.
The following is an example of how to use one of the built-in resolvers:
```ts
import { providers } from '@backstage/plugin-auth-backend';
// ...
providerFactories: {
bitbucket: providers.bitbucket.create({
signIn: {
resolver:
providers.bitbucket.resolvers.usernameMatchingUserEntityAnnotation(),
},
}),
},
```
-174
View File
@@ -1,174 +0,0 @@
---
id: provider
title: Cloudflare Access Provider
sidebar_label: Cloudflare Access
description: Adding Cloudflare Access as an authentication provider in Backstage
---
Similar to GCP IAP Proxy Provider or AWS ALB provider, developers can offload authentication
support to Cloudflare Access.
This tutorial shows how to use authentication on Cloudflare Access sitting in
front of Backstage.
It is assumed a Cloudflare tunnel is already serving traffic in front of a
Backstage instance configured to serve the frontend app from the backend and is
already gated using Cloudflare Access.
## Configuration
Let's start by adding the following `auth` configuration in your
`app-config.yaml` or `app-config.production.yaml` or similar:
```yaml
auth:
providers:
cfaccess:
# You can find the team name in the Cloudflare Zero Trust dashboard.
teamName: <Team Name>
# This service tokens section is optional -- you only need it if you have
# some Cloudflare Service Tokens that you want to be able to log in to your
# Backstage instance.
serviceTokens:
- token: '1uh2fh19efvfh129f1f919u21f2f19jf2.access'
subject: 'bot-user@your-company.com'
# This picks what sign in resolver(s) you want to use.
signIn:
resolvers:
- resolver: emailMatchingUserEntityProfileEmail
```
This config section must be in place for the provider to load at all.
The `signIn` section picks what sign-in resolver(s) to use for sign-in attempts.
It is responsible for matching the upstream provider's sign-in result to a
corresponding Backstage identity, or to throw an error if the attempt should be
rejected for any reason. The `emailMatchingUserEntityProfileEmail` is a common
choice: it tries to match the email of the signed-in user to a `User` kind
entity in the catalog whose profile email matches that.
If the builtin sign in resolvers do not match your needs, you can skip the
`signIn` section and instead [provide a custom resolver](#advanced-custom-sign-in-resolver).
## Backend Changes
We need to add the provider package as a dependency to our backend:
```bash title="from your Backstage root directory"
yarn --cwd packages/backend add @backstage/plugin-auth-backend-module-cloudflare-access-provider
```
And to tell the backend to load it:
```ts title="in packages/backend/src/index.ts"
backend.add(import('@backstage/plugin-auth-backend'));
/* highlight-add-start */
backend.add(
import('@backstage/plugin-auth-backend-module-cloudflare-access-provider'),
);
/* highlight-add-end */
```
Now the backend is ready to serve auth requests on the
`/api/auth/cfaccess/refresh` endpoint. All that's left is to update the frontend
sign-in mechanism to poll that endpoint through Cloudflare Access, on the user's
behalf.
## Frontend Changes
It is recommended to use the `ProxiedSignInPage` for this provider, which is
installed in your app like this:
```tsx title="in packages/app/src/App.tsx"
/* highlight-add-next-line */
import { ProxiedSignInPage } from '@backstage/core-components';
const app = createApp({
/* highlight-add-start */
components: {
SignInPage: props => <ProxiedSignInPage {...props} provider="cfaccess" />,
},
/* highlight-add-end */
// ...
});
```
See [Sign-In with Proxy Providers](../index.md#sign-in-with-proxy-providers) for
pointers on how to set up the sign-in page to also work smoothly for local
development.
## Advanced: Custom Sign-in Resolver
If none of the built-in sign in resolvers fit your needs, you need to provide a
customized version of the module. Now you should _not_
`backend.add(import(...))`, instead you will do the following.
```ts title="in packages/backend/plugin/auth.ts"
/* highlight-add-start */
import { createCloudflareAccessAuthenticator } from '@backstage/plugin-auth-backend-module-cloudflare-access-provider';
import {
coreServices,
createBackendModule,
} from '@backstage/backend-plugin-api';
import {
authProvidersExtensionPoint,
createProxyAuthProviderFactory,
} from '@backstage/plugin-auth-node';
const customAuth = createBackendModule({
// This ID must be exactly "auth" because that's the plugin it targets
pluginId: 'auth',
// This ID must be unique, but can be anything
moduleId: 'custom-auth-provider',
register(reg) {
reg.registerInit({
deps: {
providers: authProvidersExtensionPoint,
cache: coreServices.cache,
},
async init({ providers, cache }) {
providers.registerProvider({
// This ID must match the actual provider config, e.g. addressing
// auth.providers.github means that this must be "github".
providerId: 'cfaccess',
// Use createProxyAuthProviderFactory instead if it's one of the proxy
// based providers rather than an OAuth based one
factory: createProxyAuthProviderFactory({
authenticator: createCloudflareAccessAuthenticator({ cache }),
async signInResolver(info, ctx) {
// This is where the body of the sign-in resolver goes!
const { profile } = info;
if (!profile.email) {
throw new Error(
'Login failed, user profile does not contain an email',
);
}
return ctx.signInWithCatalogUser({
filter: {
'spec.profile.email': profile.email,
},
});
},
}),
});
},
});
},
});
/* highlight-add-end */
backend.add(import('@backstage/plugin-auth-backend'));
/* highlight-remove-start */
backend.add(
import('@backstage/plugin-auth-backend-module-cloudflare-access-provider'),
);
/* highlight-remove-end */
/* highlight-add-next-line */
backend.add(customAuth);
```
The body of the sign-in resolver is up to you to write! The example code above
is just a copy of what `emailMatchingUserEntityProfileEmail` does. The `info`
parameter contains all of the results of the sign-in attempt so far. The `ctx`
context [has several useful functions](https://backstage.io/docs/reference/plugin-auth-node.authresolvercontext/)
for issuing tokens in various ways.
+82
View File
@@ -0,0 +1,82 @@
---
id: provider
title: Cloudflare Access Provider
sidebar_label: Cloudflare Access
description: Adding Cloudflare Access as an authentication provider in Backstage
---
Similar to GCP IAP Proxy Provider or AWS ALB provider, developers can offload authentication
support to Cloudflare Access.
This tutorial shows how to use authentication on Cloudflare Access sitting in
front of Backstage.
It is assumed a Cloudflare tunnel is already serving traffic in front of a
Backstage instance configured to serve the frontend app from the backend and is
already gated using Cloudflare Access.
## Configuration
Let's start by adding the following `auth` configuration in your
`app-config.yaml` or `app-config.production.yaml` or similar:
```yaml
auth:
providers:
cfaccess:
# You can find the team name in the Cloudflare Zero Trust dashboard.
teamName: <Team Name>
# This service tokens section is optional -- you only need it if you have
# some Cloudflare Service Tokens that you want to be able to log in to your
# Backstage instance.
serviceTokens:
- token: '1uh2fh19efvfh129f1f919u21f2f19jf2.access'
subject: 'bot-user@your-company.com'
# This picks what sign in resolver(s) you want to use.
signIn:
resolvers:
- resolver: emailMatchingUserEntityProfileEmail
- resolver: emailLocalPartMatchingUserEntityName
```
This config section must be in place for the provider to load at all.
### Resolvers
This provider includes several resolvers out of the box that you can use:
- `emailMatchingUserEntityProfileEmail`: Matches the email address from the auth provider with the User entity that has a matching `spec.profile.email`. If no match is found it will throw a `NotFoundError`.
- `emailLocalPartMatchingUserEntityName`: Matches the [local part](https://en.wikipedia.org/wiki/Email_address#Local-part) of the email address from the auth provider with the User entity that has a matching `name`. If no match is found it will throw a `NotFoundError`.
:::note Note
The resolvers will be tried in order, but will only be skipped if they throw a `NotFoundError`.
:::
If these resolvers do not fit your needs you can build a custom resolver, this is covered in the [Building Custom Resolvers](../identity-resolver.md#building-custom-resolvers) section of the Sign-in Identities and Resolvers documentation.
## Backend Installation
To add the provider to the backend we will first need to install the package by running this command:
```bash title="from your Backstage root directory"
yarn --cwd packages/backend add @backstage/plugin-auth-backend-module-cloudflare-access-provider
```
Then we will need to add this line:
```ts title="in packages/backend/src/index.ts"
backend.add(import('@backstage/plugin-auth-backend'));
/* highlight-add-start */
backend.add(
import('@backstage/plugin-auth-backend-module-cloudflare-access-provider'),
);
/* highlight-add-end */
```
## Adding the provider to the Backstage frontend
See [Sign-In with Proxy Providers](../index.md#sign-in-with-proxy-providers) for pointers on how to set up the sign-in page, and to also make it work smoothly for local development. You'll use `cfaccess` as the provider name.
If you [provide a custom sign in resolver](https://backstage.io/docs/auth/identity-resolver#building-custom-resolvers), you can skip the `signIn` block entirely.
+25 -8
View File
@@ -26,6 +26,14 @@ Settings for local development:
- Homepage URL: `http://localhost:3000`
- Authorization callback URL: `http://localhost:7007/api/auth/github/handler/frame`
### Difference between GitHub Apps and GitHub OAuth Apps
GitHub Apps handle OAuth scope at the app installation level, meaning that the
`scope` parameter for the call to `getAccessToken` in the frontend has no
effect. When calling `getAccessToken` in open source plugins, one should still
include the appropriate scope, but also document in the plugin README what
scopes are required for GitHub Apps.
## Configuration
The provider configuration can then be added to your `app-config.yaml` under the
@@ -79,16 +87,25 @@ The resolvers will be tried in order, but will only be skipped if they throw a `
If these resolvers do not fit your needs you can build a custom resolver, this is covered in the [Building Custom Resolvers](../identity-resolver.md#building-custom-resolvers) section of the Sign-in Identities and Resolvers documentation.
## Backend Installation
To add the provider to the backend we will first need to install the package by running this command:
```bash title="from your Backstage root directory"
yarn --cwd packages/backend add @backstage/plugin-auth-backend-module-github-provider
```
Then we will need to add this line:
```ts title="in packages/backend/src/index.ts"
backend.add(import('@backstage/plugin-auth-backend'));
/* highlight-add-start */
backend.add(import('@backstage/plugin-auth-backend-module-github-provider'));
/* highlight-add-end */
```
## Adding the provider to the Backstage frontend
To add the provider to the frontend, add the `githubAuthApi` reference and
`SignInPage` component as shown in
[Adding the provider to the sign-in page](../index.md#adding-the-provider-to-the-sign-in-page).
## Difference between GitHub Apps and GitHub OAuth Apps
GitHub Apps handle OAuth scope at the app installation level, meaning that the
`scope` parameter for the call to `getAccessToken` in the frontend has no
effect. When calling `getAccessToken` in open source plugins, one should still
include the appropriate scope, but also document in the plugin README what
scopes are required for GitHub Apps.
+17
View File
@@ -78,6 +78,23 @@ The resolvers will be tried in order, but will only be skipped if they throw a `
If these resolvers do not fit your needs you can build a custom resolver, this is covered in the [Building Custom Resolvers](../identity-resolver.md#building-custom-resolvers) section of the Sign-in Identities and Resolvers documentation.
## Backend Installation
To add the provider to the backend we will first need to install the package by running this command:
```bash title="from your Backstage root directory"
yarn --cwd packages/backend add @backstage/plugin-auth-backend-module-gitlab-provider
```
Then we will need to add this line:
```ts title="in packages/backend/src/index.ts"
backend.add(import('@backstage/plugin-auth-backend'));
/* highlight-add-start */
backend.add(import('@backstage/plugin-auth-backend-module-gitlab-provider'));
/* highlight-add-end */
```
## Adding the provider to the Backstage frontend
To add the provider to the frontend, add the `gitlabAuthApi` reference and
+9 -86
View File
@@ -58,102 +58,25 @@ The resolvers will be tried in order, but will only be skipped if they throw a `
If these resolvers do not fit your needs you can build a custom resolver, this is covered in the [Building Custom Resolvers](../identity-resolver.md#building-custom-resolvers) section of the Sign-in Identities and Resolvers documentation.
## Backend Changes
## Backend Installation
There is a module for this provider that you will need to add to your backend.
To add the provider to the backend we will first need to install the package by running this command:
First you'll want to run this command to add the module:
```sh
yarn --cwd packages/backend add @backstage/plugin-auth-backend-module-gcp-iap-provider
```bash title="from your Backstage root directory"
yarn --cwd packages/backend add @backstage/plugin-auth-backend-module-gcp-iap-provider
```
Then you will need to add this to your backend:
```ts title="packages/backend/src/index.ts"
const backend = createBackend();
Then we will need to add this line:
```ts title="in packages/backend/src/index.ts"
backend.add(import('@backstage/plugin-auth-backend'));
/* highlight-add-start */
backend.add(import('@backstage/plugin-auth-backend-module-gcp-iap-provider'));
/* highlight-add-end */
```
### Legacy Backend Changes
## Adding the provider to the Backstage frontend
If you are still using the legacy backend you will need to make the changes outlined here.
See [Sign-In with Proxy Providers](../index.md#sign-in-with-proxy-providers) for pointers on how to set up the sign-in page, and to also make it work smoothly for local development. You'll use `gcp-iap` as the provider name.
This provider is not enabled by default in the auth backend code, because besides the config section above, it also needs to be given one or more callbacks in actual code as well as described below.
Add a `providerFactories` entry to the router in
`packages/backend/src/plugins/auth.ts`.
```ts title="packages/backend/src/plugins/auth.ts"
import { providers } from '@backstage/plugin-auth-backend';
import { stringifyEntityRef } from '@backstage/catalog-model';
export default async function createPlugin(
env: PluginEnvironment,
): Promise<Router> {
return await createRouter({
logger: env.logger,
config: env.config,
database: env.database,
discovery: env.discovery,
providerFactories: {
'gcp-iap': providers.gcpIap.create({
// Replace the auth handler if you want to customize the returned user
// profile info (can be left out; the default implementation is shown
// below which only returns the email). You may want to amend this code
// with something that loads additional user profile data out of e.g.
// GSuite or LDAP or similar.
async authHandler({ iapToken }) {
return { profile: { email: iapToken.email } };
},
signIn: {
// You need to supply an identity resolver, that takes the profile
// and the IAP token and produces the Backstage token with the
// relevant user info.
async resolver({ profile, result: { iapToken } }, ctx) {
// Somehow compute the Backstage token claims. Just some sample code
// shown here, but you may want to query your LDAP server, or
// GSuite or similar, based on the IAP token sub/email claims
const id = iapToken.email.split('@')[0];
const sub = stringifyEntityRef({ kind: 'User', name: id });
const ent = [
sub,
stringifyEntityRef({ kind: 'Group', name: 'team-name' }),
];
return ctx.issueToken({ claims: { sub, ent } });
},
},
}),
},
});
}
```
Now the backend is ready to serve auth requests on the
`/api/auth/gcp-iap/refresh` endpoint. All that's left is to update the frontend
sign-in mechanism to poll that endpoint through the IAP, on the user's behalf.
## Frontend Changes
It is recommended to use the `ProxiedSignInPage` for this provider, which is
installed in `packages/app/src/App.tsx` like this:
```tsx title="packages/app/src/App.tsx"
/* highlight-add-next-line */
import { ProxiedSignInPage } from '@backstage/core-components';
const app = createApp({
/* highlight-add-start */
components: {
SignInPage: props => <ProxiedSignInPage {...props} provider="gcp-iap" />,
},
/* highlight-add-end */
// ..
});
```
See the [Sign-In with Proxy Providers](../index.md#sign-in-with-proxy-providers) section for more information.
If you [provide a custom sign in resolver](https://backstage.io/docs/auth/identity-resolver#building-custom-resolvers), you can skip the `signIn` block entirely.
+19 -2
View File
@@ -24,9 +24,9 @@ To support Google authentication, you must create OAuth credentials:
- Add yourself as a test user, if using External user type
6. Set **Application Type** to `Web Application` with these settings:
- `Name`: Backstage (or your custom app name)
- `Authorized JavaScript origins`: http://localhost:3000
- `Authorized JavaScript origins`: <http://localhost:3000>
- `Authorized Redirect URIs`:
http://localhost:7007/api/auth/google/handler/frame
<http://localhost:7007/api/auth/google/handler/frame>
7. Click Create
## Configuration
@@ -72,6 +72,23 @@ The resolvers will be tried in order, but will only be skipped if they throw a `
If these resolvers do not fit your needs you can build a custom resolver, this is covered in the [Building Custom Resolvers](../identity-resolver.md#building-custom-resolvers) section of the Sign-in Identities and Resolvers documentation.
## Backend Installation
To add the provider to the backend we will first need to install the package by running this command:
```bash title="from your Backstage root directory"
yarn --cwd packages/backend add @backstage/plugin-auth-backend-module-google-provider
```
Then we will need to add this line:
```ts title="in packages/backend/src/index.ts"
backend.add(import('@backstage/plugin-auth-backend'));
/* highlight-add-start */
backend.add(import('@backstage/plugin-auth-backend-module-google-provider'));
/* highlight-add-end */
```
## Adding the provider to the Backstage frontend
To add the provider to the frontend, add the `googleAuthApi` reference and
+2
View File
@@ -124,6 +124,8 @@ The list of available resolvers is different for each provider, since they often
depend on the information model returned from the upstream provider service.
Consult the documentation of the respective provider to find the list.
In the example above `emailMatchingUserEntityProfileEmail` and `emailLocalPartMatchingUserEntityName` are common to all auth providers and `usernameMatchingUserEntityName` is specific to GitHub.
### Building Custom Resolvers
If the builtins don't work for you, you can also provide a completely custom
+56 -81
View File
@@ -7,87 +7,6 @@ description: Adding Azure's EasyAuth Proxy as an authentication provider in Back
The Backstage `core-plugin-api` package comes with a Microsoft authentication provider that can authenticate users using Microsoft Entra ID (formerly Azure Active Directory) for PaaS service hosted in Azure that support Easy Auth, such as Azure App Services.
## Backend Changes
Add the following into your `app-config.yaml` under the root `auth` configuration:
```yaml title="app-config.yaml"
auth:
providers:
azureEasyAuth:
signIn:
resolvers:
- resolver: idMatchingUserEntityAnnotation
- resolver: emailMatchingUserEntityProfileEmail
- resolver: emailLocalPartMatchingUserEntityName
```
The `idMatchingUserEntityAnnotation` is
[a builtin sign-in resolver](../identity-resolver.md#using-builtin-resolvers) from `azureEasyAuth` provider.
It tries to find a user entity with [a `graph.microsoft.com/user-id` annotation](../../features/software-catalog/well-known-annotations.md#graphmicrosoftcomtenant-id-graphmicrosoftcomgroup-id-graphmicrosoftcomuser-id)
which matches the object ID of the user attempting to sign in.
If you want to provide your own sign-in resolver,
see [Building Custom Resolvers](../identity-resolver.md#building-custom-resolvers).
Add the `@backstage/plugin-auth-backend-module-azure-easyauth-provider` to your backend installation.
```sh
# From your Backstage root directory
yarn --cwd packages/backend add @backstage/plugin-auth-backend-module-azure-easyauth-provider
```
Then, add it to your backend's source,
```ts title="packages/backend/src/index.ts"
const backend = createBackend();
backend.add(import('@backstage/plugin-auth-backend'));
// highlight-add-next-line
backend.add(
import('@backstage/plugin-auth-backend-module-azure-easyauth-provider'),
);
await backend.start();
```
Now the backend is ready to serve auth requests on the
`/api/auth/azureEasyAuth/refresh` endpoint. All that's left is to update the frontend
sign-in mechanism to poll that endpoint through the Easy Auth proxy, on the user's behalf.
## Frontend Changes
To use this component, you'll need to configure the app's `SignInPage`.
It is recommended to use the `ProxiedSignInPage` for this provider when running in Azure, However for local development (or any other scenario running outside of Azure), you'll want to set up something different.
For the closest experience to Easy Auth, you could set up the `microsoft` provider locally, but that will requires setting up App Registrations & secrets which may be locked down by your organisation, in which case it may be easier to use guest login locally.
See [Sign-In with Proxy Providers](../index.md#sign-in-with-proxy-providers) for more details.
```tsx title="packages/app/src/App.tsx"
/* highlight-add-next-line */
import { ProxiedSignInPage } from '@backstage/core-components';
const app = createApp({
/* highlight-add-start */
components: {
SignInPage: props => {
const configApi = useApi(configApiRef);
if (configApi.getString('auth.environment') !== 'development') {
return <ProxiedSignInPage {...props} provider="azureEasyAuth" />;
}
return (
<SignInPage
{...props}
providers={['guest', 'custom']}
title="Select a sign-in method"
align="center"
/>
);
},
},
/* highlight-add-end */
// ..
});
```
## Azure Configuration
How to configure azure depends on the Azure service you're using to host Backstage.
@@ -136,3 +55,59 @@ resource webApp 'Microsoft.Web/sites@2022-03-01' existing = {
}
}
```
## Configuration
Add the following into your `app-config.yaml` under the root `auth` configuration:
```yaml title="app-config.yaml"
auth:
providers:
azureEasyAuth:
signIn:
resolvers:
- resolver: emailMatchingUserEntityProfileEmail
- resolver: emailLocalPartMatchingUserEntityName
- resolver: idMatchingUserEntityAnnotation
```
### Resolvers
This provider includes several resolvers out of the box that you can use:
- `emailMatchingUserEntityProfileEmail`: Matches the email address from the auth provider with the User entity that has a matching `spec.profile.email`. If no match is found it will throw a `NotFoundError`.
- `emailLocalPartMatchingUserEntityName`: Matches the [local part](https://en.wikipedia.org/wiki/Email_address#Local-part) of the email address from the auth provider with the User entity that has a matching `name`. If no match is found it will throw a `NotFoundError`.
- `idMatchingUserEntityAnnotation`: Matches the user Id from the auth provider with the User entity that has a matching `graph.microsoft.com/user-id` annotation. If no match is found it will throw a `NotFoundError`.
:::note Note
The resolvers will be tried in order, but will only be skipped if they throw a `NotFoundError`.
:::
If these resolvers do not fit your needs you can build a custom resolver, this is covered in the [Building Custom Resolvers](../identity-resolver.md#building-custom-resolvers) section of the Sign-in Identities and Resolvers documentation.
## Backend Installation
To add the provider to the backend we will first need to install the package by running this command:
```bash title="from your Backstage root directory"
yarn --cwd packages/backend add @backstage/plugin-auth-backend-module-azure-easyauth-provider
```
Then we will need to this line:
```ts title="in packages/backend/src/index.ts"
backend.add(import('@backstage/plugin-auth-backend'));
/* highlight-add-start */
backend.add(
import('@backstage/plugin-auth-backend-module-azure-easyauth-provider'),
);
/* highlight-add-end */
```
## Adding the provider to the Backstage frontend
See [Sign-In with Proxy Providers](../index.md#sign-in-with-proxy-providers) for pointers on how to set up the sign-in page, and to also make it work smoothly for local development. You'll use `azureEasyAuth` as the provider name.
If you [provide a custom sign in resolver](https://backstage.io/docs/auth/identity-resolver#building-custom-resolvers), you can skip the `signIn` block entirely.
+29 -12
View File
@@ -40,6 +40,18 @@ If you're using an existing app registration, and backstage already has a client
If not, go to the **Certificates & Secrets** page, then the **Client secrets** tab and create a new client secret.
Make a note of this value as you'll need it in the next section.
## Outbound Network Access
If your environment has restrictions on outgoing access (e.g. through
firewall rules), make sure your Backstage backend has access to the following
hosts:
- `login.microsoftonline.com`, to get and exchange authorization codes and access
tokens
- `graph.microsoft.com`, to fetch user profile information (as seen
in [this source code](https://github.com/seanfisher/passport-microsoft/blob/0456aa9bce05579c18e77f51330176eb26373658/lib/strategy.js#L93-L95)).
If this host is unreachable, users may see an `Authentication failed, failed to fetch user profile` error when they attempt to log in.
## Configuration
The provider configuration can then be added to your `app-config.yaml` under the
@@ -92,20 +104,25 @@ The resolvers will be tried in order, but will only be skipped if they throw a `
If these resolvers do not fit your needs you can build a custom resolver, this is covered in the [Building Custom Resolvers](../identity-resolver.md#building-custom-resolvers) section of the Sign-in Identities and Resolvers documentation.
## Backend Installation
To add the provider to the backend we will first need to install the package by running this command:
```bash title="from your Backstage root directory"
yarn --cwd packages/backend add @backstage/plugin-auth-backend-module-microsoft-provider
```
Then we will need to this line:
```ts title="in packages/backend/src/index.ts"
backend.add(import('@backstage/plugin-auth-backend'));
/* highlight-add-start */
backend.add(import('@backstage/plugin-auth-backend-module-microsoft-provider'));
/* highlight-add-end */
```
## Adding the provider to the Backstage frontend
To add the provider to the frontend, add the `microsoftAuthApiRef` reference and
`SignInPage` component as shown in
[Adding the provider to the sign-in page](../index.md#adding-the-provider-to-the-sign-in-page).
## Outbound Network Access
If your environment has restrictions on outgoing access (e.g. through
firewall rules), make sure your Backstage backend has access to the following
hosts:
- `login.microsoftonline.com`, to get and exchange authorization codes and access
tokens
- `graph.microsoft.com`, to fetch user profile information (as seen
in [this source code](https://github.com/seanfisher/passport-microsoft/blob/0456aa9bce05579c18e77f51330176eb26373658/lib/strategy.js#L93-L95)).
If this host is unreachable, users may see an `Authentication failed, failed to fetch user profile` error when they attempt to log in.
+20 -18
View File
@@ -47,25 +47,27 @@ The resolvers will be tried in order, but will only be skipped if they throw a `
If these resolvers do not fit your needs you can build a custom resolver, this is covered in the [Building Custom Resolvers](../identity-resolver.md#building-custom-resolvers) section of the Sign-in Identities and Resolvers documentation.
## Adding the provider to the Backstage frontend
## Backend Installation
It is recommended to use the `ProxiedSignInPage` for this provider, which is
installed in `packages/app/src/App.tsx` like this:
To add the provider to the backend we will first need to install the package by running this command:
```tsx title="packages/app/src/App.tsx"
/* highlight-add-next-line */
import { ProxiedSignInPage } from '@backstage/core-components';
const app = createApp({
/* highlight-add-start */
components: {
SignInPage: props => (
<ProxiedSignInPage {...props} provider="oauth2Proxy" />
),
},
/* highlight-add-end */
// ..
});
```bash title="from your Backstage root directory"
yarn --cwd packages/backend add @backstage/plugin-auth-backend-module-oauth2-proxy-provider
```
See [Sign-In with Proxy Providers](../index.md#sign-in-with-proxy-providers) for pointers on how to set up the sign-in page to also work smoothly for local development.
Then we will need to this line:
```ts title="in packages/backend/src/index.ts"
backend.add(import('@backstage/plugin-auth-backend'));
/* highlight-add-start */
backend.add(
import('@backstage/plugin-auth-backend-module-oauth2-proxy-provider'),
);
/* highlight-add-end */
```
## Adding the provider to the Backstage frontend
See [Sign-In with Proxy Providers](../index.md#sign-in-with-proxy-providers) for pointers on how to set up the sign-in page, and to also make it work smoothly for local development. You'll use `oauth2Proxy` as the provider name.
If you [provide a custom sign in resolver](https://backstage.io/docs/auth/identity-resolver#building-custom-resolvers), you can skip the `signIn` block entirely.
+17
View File
@@ -83,6 +83,23 @@ The resolvers will be tried in order, but will only be skipped if they throw a `
If these resolvers do not fit your needs you can build a custom resolver, this is covered in the [Building Custom Resolvers](../identity-resolver.md#building-custom-resolvers) section of the Sign-in Identities and Resolvers documentation.
## Backend Installation
To add the provider to the backend we will first need to install the package by running this command:
```bash title="from your Backstage root directory"
yarn --cwd packages/backend add @backstage/plugin-auth-backend-module-okta-provider
```
Then we will need to add this line:
```ts title="in packages/backend/src/index.ts"
backend.add(import('@backstage/plugin-auth-backend'));
/* highlight-add-start */
backend.add(import('@backstage/plugin-auth-backend-module-okta-provider'));
/* highlight-add-end */
```
## Adding the provider to the Backstage frontend
To add the provider to the frontend, add the `oktaAuthApi` reference and
+39
View File
@@ -38,6 +38,12 @@ auth:
clientId: ${AUTH_ONELOGIN_CLIENT_ID}
clientSecret: ${AUTH_ONELOGIN_CLIENT_SECRET}
issuer: https://<company>.onelogin.com/oidc/2
signIn:
resolvers:
# typically you would pick one of these
- resolver: emailMatchingUserEntityProfileEmail
- resolver: emailLocalPartMatchingUserEntityName
- resolver: usernameMatchingUserEntityName
```
The OneLogin provider is a structure with three configuration keys; **these are
@@ -47,6 +53,39 @@ found on the SSO tab** for the OneLogin Application:
- `clientSecret`: The client secret
- `issuer`: The issuer URL
### Resolvers
This provider includes several resolvers out of the box that you can use:
- `emailMatchingUserEntityProfileEmail`: Matches the email address from the auth provider with the User entity that has a matching `spec.profile.email`. If no match is found it will throw a `NotFoundError`.
- `emailLocalPartMatchingUserEntityName`: Matches the [local part](https://en.wikipedia.org/wiki/Email_address#Local-part) of the email address from the auth provider with the User entity that has a matching `name`. If no match is found it will throw a `NotFoundError`.
- `usernameMatchingUserEntityName`: Matches the username from the auth provider with the User entity that has a matching `name`. If no match is found it will throw a `NotFoundError`.
:::note Note
The resolvers will be tried in order, but will only be skipped if they throw a `NotFoundError`.
:::
If these resolvers do not fit your needs you can build a custom resolver, this is covered in the [Building Custom Resolvers](../identity-resolver.md#building-custom-resolvers) section of the Sign-in Identities and Resolvers documentation.
## Backend Installation
To add the provider to the backend we will first need to install the package by running this command:
```bash title="from your Backstage root directory"
yarn --cwd packages/backend add @backstage/plugin-auth-backend-module-onelogin-provider
```
Then we will need to add this line:
```ts title="in packages/backend/src/index.ts"
backend.add(import('@backstage/plugin-auth-backend'));
/* highlight-add-start */
backend.add(import('@backstage/plugin-auth-backend-module-onelogin-provider'));
/* highlight-add-end */
```
## Adding the provider to the Backstage frontend
To add the provider to the frontend, add the `oneloginAuthApi` reference and
+30 -103
View File
@@ -33,108 +33,6 @@ Cloud Console and within a Backstage app required to enable this capability.
1. Take note of the `App ID` in the resulting modal; this is the client ID to be
used by Backstage.
## Install the provider in the backend
### New backend system
Apps using the [new backend system](../../backend-system/index.md),
can enable the VMware Cloud provider with a small modification like:
```ts title="packages/backend/src/index.ts"
import { createBackend } from '@backstage/backend-defaults';
const backend = createBackend();
backend.add(import('@backstage/plugin-auth-backend'));
/* highlight-add-start */
backend.add(
import('@backstage/plugin-auth-backend-module-vmware-cloud-provider'),
);
/* highlight-add-end */
backend.start();
```
### Old backend system
This provider was added after the migration of the auth-backend plugin to the
new backend system, so no default provider factory was added. Because of this,
the installation procedure for old-style backends is slightly more involved:
```ts title="packages/backend/src/plugins/auth.ts"
import {
DEFAULT_NAMESPACE,
stringifyEntityRef,
} from '@backstage/catalog-model';
import {
createRouter,
providers,
defaultAuthProviderFactories,
} from '@backstage/plugin-auth-backend';
import { Router } from 'express';
import { PluginEnvironment } from '../types';
/* highlight-add-start */
import {
commonSignInResolvers,
createOAuthProviderFactory,
} from '@backstage/plugin-auth-node';
import {
vmwareCloudAuthenticator,
} from '@backstage/plugin-auth-backend-module-vmware-cloud-provider';
/* highlight-add-end */
export default async function createPlugin(
env: PluginEnvironment,
): Promise<Router> {
return await createRouter({
logger: env.logger,
config: env.config,
database: env.database,
discovery: env.discovery,
tokenManager: env.tokenManager,
providerFactories: {
...defaultAuthProviderFactories,
/* highlight-add-start */
vmwareCloudServices: createOAuthProviderFactory({
authenticator: vmwareCloudAuthenticator,
signInResolver:
commonSignInResolvers.emailLocalPartMatchingUserEntityName(),
}),
/* highlight-add-end */
```
In the above, `commonSignInResolvers.emailLocalPartMatchingUserEntityName()`
can be replaced with a more suitable resolver for the app in question.
## Add to Sign-in Page
See the [Sign-In Configuration](../index.md#sign-in-configuration) docs for
general guidance, but as an example:
```tsx title="packages/app/src/App.tsx"
/* highlight-add-start */
import { vmwareCloudAuthApiRef } from '@backstage/core-plugin-api';
import { SignInPage } from '@backstage/core-components';
/* highlight-add-end */
const app = createApp({
/* highlight-add-start */
components: {
SignInPage: props => (
<SignInPage
{...props}
provider={{
id: 'vmware-cloud-auth-provider',
title: 'VMware Cloud',
message: 'Sign in using VMware Cloud',
apiRef: vmwareCloudAuthApiRef,
}}
/>
),
},
/* highlight-add-end */
// ..
});
```
## Configuration
Add the following to your `app-config.yaml` under the root `auth` configuration:
@@ -161,13 +59,17 @@ Where `APP_ID` refers to the ID retrieved when creating the OAuth App, and
`ORG_ID` is the [long ID of the Organization](https://docs.vmware.com/en/VMware-Cloud-services/services/Using-VMware-Cloud-Services/GUID-CF9E9318-B811-48CF-8499-9419997DC1F8.html#view-the-organization-id-1)
in VMware Cloud for which you wish to enable sign-in.
Note that VMware Cloud requires OAuth Apps to use
:::note Note
VMware Cloud requires OAuth Apps to use
[PKCE](https://oauth.net/2/pkce/) when performing authorization code flows; the
library used by this provider requires the use of Express session middleware to
do this. Therefore the value `your session secret` under `auth.session.secret`
should be replaced with a long, complex and unique string which will act as a
key for signing session cookies set by Backstage.
:::
### Resolvers
This provider includes several resolvers out of the box that you can use:
@@ -183,3 +85,28 @@ The resolvers will be tried in order, but will only be skipped if they throw a `
:::
If these resolvers do not fit your needs you can build a custom resolver, this is covered in the [Building Custom Resolvers](../identity-resolver.md#building-custom-resolvers) section of the Sign-in Identities and Resolvers documentation.
## Backend Installation
To add the provider to the backend we will first need to install the package by running this command:
```bash title="from your Backstage root directory"
yarn --cwd packages/backend add @backstage/plugin-auth-backend-module-vmware-cloud-provider
```
Then we will need to this line:
```ts title="in packages/backend/src/index.ts"
backend.add(import('@backstage/plugin-auth-backend'));
/* highlight-add-start */
backend.add(
import('@backstage/plugin-auth-backend-module-vmware-cloud-provider'),
);
/* highlight-add-end */
```
## Adding the provider to the Backstage frontend
To add the provider to the frontend, add the `vmwareCloudAuthApiRef` reference and
`SignInPage` component as shown in
[Adding the provider to the sign-in page](../index.md#adding-the-provider-to-the-sign-in-page).