Merge pull request #24221 from awanlin/topic/auth-providers-signin-resolvers

[NBS Docs] Added SingIn Resolvers Config Details
This commit is contained in:
Patrik Oldsberg
2024-05-01 16:08:51 +02:00
committed by GitHub
10 changed files with 187 additions and 43 deletions
+18
View File
@@ -47,6 +47,12 @@ auth:
clientId: ${AUTH_ATLASSIAN_CLIENT_ID}
clientSecret: ${AUTH_ATLASSIAN_CLIENT_SECRET}
scope: ${AUTH_ATLASSIAN_SCOPES}
signIn:
resolvers:
# typically you would pick one of these
- resolver: emailMatchingUserEntityProfileEmail
- resolver: emailLocalPartMatchingUserEntityName
- resolver: usernameMatchingUserEntityName
```
The Atlassian provider is a structure with three configuration keys:
@@ -57,6 +63,18 @@ The Atlassian provider is a structure with three configuration keys:
**NOTE:** the scopes `offline_access`, `read:jira-work`, and `read:jira-user` are provided by default.
### 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: 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.
## Adding the provider to the Backstage frontend
To add the provider to the frontend, add the `atlassianAuthApi` reference and
+18
View File
@@ -41,6 +41,12 @@ auth:
clientSecret: ${AUTH_GITHUB_CLIENT_SECRET}
## uncomment if using GitHub Enterprise
# enterpriseInstanceUrl: ${AUTH_GITHUB_ENTERPRISE_INSTANCE_URL}
signIn:
resolvers:
# typically you would pick one of these
- resolver: emailMatchingUserEntityProfileEmail
- resolver: emailLocalPartMatchingUserEntityName
- resolver: usernameMatchingUserEntityName
```
The GitHub provider is a structure with three configuration keys:
@@ -55,6 +61,18 @@ The GitHub provider is a structure with three configuration keys:
`https://your-intermediate-service.com/handler`. Only needed if Backstage is
not the immediate receiver (e.g. one OAuth app for many backstage instances).
### 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: 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.
## Adding the provider to the Backstage frontend
To add the provider to the frontend, add the `githubAuthApi` reference and
+18
View File
@@ -43,6 +43,12 @@ auth:
# audience: https://gitlab.company.com
## uncomment if using a custom redirect URI
# callbackUrl: https://${BASE_URL}/api/auth/gitlab/handler/frame
signIn:
resolvers:
# typically you would pick one of these
- resolver: emailMatchingUserEntityProfileEmail
- resolver: emailLocalPartMatchingUserEntityName
- resolver: usernameMatchingUserEntityName
```
The GitLab provider is a structure with three configuration keys:
@@ -56,6 +62,18 @@ The GitLab provider is a structure with three configuration keys:
`https://$backstage.acme.corp/api/auth/gitlab/handler/frame`
Note: Due to a peculiarity with GitLab OAuth, ensure there is no trailing `/` after 'frame' in the 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: 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.
## Adding the provider to the Backstage frontend
To add the provider to the frontend, add the `gitlabAuthApi` reference and
+42 -3
View File
@@ -27,6 +27,12 @@ auth:
gcp-iap:
audience: '/projects/<project number>/global/backendServices/<backend service id>'
jwtHeader: x-custom-header # Optional: Only if you are using a custom header for the IAP JWT
signIn:
resolvers:
# typically you would pick one of these
- resolver: emailMatchingUserEntityProfileEmail
- resolver: emailLocalPartMatchingUserEntityName
- resolver: emailMatchingUserEntityAnnotation
```
The full `audience` value can be obtained by visiting your [Identity-Aware Proxy Google Cloud console](https://console.cloud.google.com/security/iap), selecting your project, finding your Backend Service to proxy, clicking the 3 vertical dots then "Get JWT Audience Code", and copying from the resulting popup, which will look similar to the following:
@@ -36,11 +42,44 @@ The full `audience` value can be obtained by visiting your [Identity-Aware Proxy
This config section must be in place for the provider to load at all. Now let's
add the provider itself.
### 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`.
- `emailMatchingUserEntityAnnotation`: Matches the email address from the auth provider with the User entity where the value of the `google.com/email` annotation matches. If no match is found it will throw a `NotFoundError`.
> 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 Changes
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.
There is a module for this provider that you will need to add to your backend.
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
```
Then you will need to add this to your backend:
```ts title="packages/backend/src/index.ts"
const backend = createBackend();
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
If you are still using the legacy backend you will need to make the changes outlined here.
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`.
+18
View File
@@ -42,6 +42,12 @@ auth:
development:
clientId: ${AUTH_GOOGLE_CLIENT_ID}
clientSecret: ${AUTH_GOOGLE_CLIENT_SECRET}
signIn:
resolvers:
# typically you would pick one of these
- resolver: emailMatchingUserEntityProfileEmail
- resolver: emailLocalPartMatchingUserEntityName
- resolver: emailMatchingUserEntityAnnotation
```
The Google provider is a structure with two configuration keys:
@@ -50,6 +56,18 @@ The Google provider is a structure with two configuration keys:
`10023341500512-beui241gjwwkrdkr2eh7dprewj2pp1q.apps.googleusercontent.com`
- `clientSecret`: The client secret tied to the generated client ID.
### 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`.
- `emailMatchingUserEntityAnnotation`: Matches the email address from the auth provider with the User entity where the value of the `google.com/email` annotation matches. If no match is found it will throw a `NotFoundError`.
> 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.
## Adding the provider to the Backstage frontend
To add the provider to the frontend, add the `googleAuthApi` reference and
+18
View File
@@ -57,6 +57,12 @@ auth:
domainHint: ${AZURE_TENANT_ID}
additionalScopes:
- Mail.Send
signIn:
resolvers:
# typically you would pick one of these
- resolver: emailMatchingUserEntityProfileEmail
- resolver: emailLocalPartMatchingUserEntityName
- resolver: emailMatchingUserEntityAnnotation
```
The Microsoft provider is a structure with three mandatory configuration keys:
@@ -70,6 +76,18 @@ The Microsoft provider is a structure with three mandatory configuration keys:
For more details, see [Home Realm Discovery](https://learn.microsoft.com/en-us/azure/active-directory/manage-apps/home-realm-discovery-policy)
- `additionalScopes` (optional): List of scopes for the App Registration. The default and mandatory value is ['user.read'].
### 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`.
- `emailMatchingUserEntityAnnotation`: Matches the email address from the auth provider with the User entity where the value of the `microsoft.com/email` annotation matches. If no match is found it will throw a `NotFoundError`.
> 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.
## Adding the provider to the Backstage frontend
To add the provider to the frontend, add the `microsoftAuthApiRef` reference and
+15 -32
View File
@@ -22,44 +22,27 @@ The provider configuration can be added to your `app-config.yaml` under the root
auth:
environment: development
providers:
oauth2Proxy: {}
oauth2Proxy:
development:
signIn:
resolvers:
# typically you would pick one of these
- resolver: emailMatchingUserEntityProfileEmail
- resolver: emailLocalPartMatchingUserEntityName
- resolver: forwardedUserMatchingUserEntityName
```
Right now no configuration options are supported, but the empty object is needed
to enable the provider in the auth backend.
### Resolvers
To use the `oauth2Proxy` provider you must also configure it with a sign-in resolver.
For more information about the sign-in process in general, see the
[Sign-in Identities and Resolvers](../identity-resolver.md) documentation.
This provider includes several resolvers out of the box that you can use:
For the `oauth2Proxy` provider, the sign-in result is quite different than other providers.
Because it's a proxy provider that can be configured to forward information through
arbitrary headers, the auth result simply just gives you access to the HTTP headers
of the incoming request. Using these you can either extract the information directly,
or grab ID or access tokens to look up additional information and/or validate the request.
- `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`.
- `forwardedUserMatchingUserEntityName`: Matches the value in the `x-forwarded-user` header from the auth provider with the User entity that has a matching `name`. If no match is found it will throw a `NotFoundError`.
A simple sign-in resolver might for example look like this:
> Note: The resolvers will be tried in order, but will only be skipped if they throw a `NotFoundError`.
```ts
providerFactories: {
...defaultAuthProviderFactories,
oauth2Proxy: providers.oauth2Proxy.create({
signIn: {
async resolver({ result }, ctx) {
const name = result.getHeader('x-forwarded-user');
if (!name) {
throw new Error('Request did not contain a user')
}
return ctx.signInWithCatalogUser({
entityRef: { name },
});
},
},
}),
},
```
[An example on how to sign a user in without a matching user](https://github.com/backstage/backstage/blob/master/packages/backend/src/plugins/auth.ts)
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
+19 -1
View File
@@ -29,7 +29,7 @@ To add Okta authentication, you must create an Application from Okta:
The configuration examples provided above are suitable for local development. For a production deployment, substitute `http://localhost:7007` with the url that your Backstage instance is available at.
# Configuration
## Configuration
The provider configuration can then be added to your `app-config.yaml` under the
root `auth` configuration:
@@ -47,6 +47,12 @@ auth:
idp: ${AUTH_OKTA_IDP} # Optional
# https://developer.okta.com/docs/reference/api/oidc/#scope-dependent-claims-not-always-returned
additionalScopes: ${AUTH_OKTA_ADDITIONAL_SCOPES} # Optional
signIn:
resolvers:
# typically you would pick one of these
- resolver: emailMatchingUserEntityProfileEmail
- resolver: emailLocalPartMatchingUserEntityName
- resolver: emailMatchingUserEntityAnnotation
```
The values referenced are found on the Application page on your Okta site.
@@ -61,6 +67,18 @@ The values referenced are found on the Application page on your Okta site.
`additionalScopes` is an optional value, a string of space separated scopes, that will be combined with the default `scope` value of `openid profile email offline_access` to adjust the `scope` sent to Okta during OAuth. This will have an impact on [the dependent claims returned](https://developer.okta.com/docs/reference/api/oidc/#scope-dependent-claims-not-always-returned). For example, setting the `additionalScopes` value to `groups` will result in the claim returning a list of the groups that the user is a member of that also match the ID token group filter of the client app.
### 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`.
- `emailMatchingUserEntityAnnotation`: Matches the email address from the auth provider with the User entity where the value of the `okta.com/email` annotation matches. If no match is found it will throw a `NotFoundError`.
> 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.
## Adding the provider to the Backstage frontend
To add the provider to the frontend, add the `oktaAuthApi` reference and
+19 -5
View File
@@ -107,10 +107,6 @@ export default async function createPlugin(
In the above, `commonSignInResolvers.emailLocalPartMatchingUserEntityName()`
can be replaced with a more suitable resolver for the app in question.
## Configure Sign-in Resolution
See [Sign-in Identities and Resolvers](../identity-resolver.md) for details.
## Add to Sign-in Page
See the [Sign-In Configuration](../index.md#sign-in-configuration) docs for
@@ -156,9 +152,15 @@ auth:
development:
clientId: ${APP_ID}
organizationId: ${ORG_ID}
signIn:
resolvers:
# typically you would pick one of these
- resolver: emailMatchingUserEntityProfileEmail
- resolver: emailLocalPartMatchingUserEntityName
- resolver: vmwareCloudSignInResolvers
```
where `APP_ID` refers to the ID retrieved when creating the OAuth App, and
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.
@@ -169,3 +171,15 @@ 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:
- `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`.
- `vmwareCloudSignInResolvers`: 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 sign in the user without associating with a catalog user.
> 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.
@@ -816,9 +816,9 @@ auth:
tenantId: ${AZURE_TENANT_ID}
signIn:
resolvers:
- resolver: emailMatchingUserEntityAnnotation
- resolver: emailMatchingUserEntityProfileEmail
- resolver: emailLocalPartMatchingUserEntityName
- resolver: emailMatchingUserEntityAnnotation
```
> Note: the resolvers will be tried in order, but will only be skipped if they throw a `NotFoundError`.
@@ -848,7 +848,7 @@ Additional resolvers:
- [usernameMatchingUserEntityName](https://github.com/backstage/backstage/blob/5447cffd23cf00772988fb799ced0ec5e54efb2e/plugins/auth-backend-module-atlassian-provider/src/resolvers.ts#L33C16-L33C46)
##### GCP IAM
##### GCP IAP (Google Identity-Aware Proxy)
Setup: