Merge pull request #11978 from backstage/rugvip/authdocs
docs: merge and clean up auth contribution docs
This commit is contained in:
+179
-98
@@ -1,9 +1,113 @@
|
||||
---
|
||||
id: add-auth-provider
|
||||
title: Adding authentication providers
|
||||
description: Documentation on Adding authentication providers
|
||||
title: Contributing New Providers
|
||||
description: Documentation on adding new authentication providers
|
||||
---
|
||||
|
||||
> NOTE: The primary audience for this documentation are contributors to the main
|
||||
> Backstage project that want to add support for new authentication providers.
|
||||
> While you can follow it to implement your own custom providers it is much
|
||||
> more advanced than using our built-in providers.
|
||||
|
||||
## How Does Authentication Work?
|
||||
|
||||
The Backstage application can use various external authentication providers for
|
||||
authentication. An external provider is wrapped using an
|
||||
`AuthProviderRouteHandlers` interface for handling authentication. This
|
||||
interface consists of four methods. Each of these methods is hosted at an
|
||||
endpoint (by default) `/api/auth/[provider]/method`, where `method` performs a
|
||||
certain operation as follows:
|
||||
|
||||
```
|
||||
/auth/[provider]/start -> Initiate a login from the web page
|
||||
/auth/[provider]/handler/frame -> Handle a finished authentication operation
|
||||
/auth/[provider]/refresh -> Refresh the validity of a login
|
||||
/auth/[provider]/logout -> Log out a logged-in user
|
||||
```
|
||||
|
||||
The flow is as follows:
|
||||
|
||||
1. A user attempts to sign in.
|
||||
2. A popup window is opened, pointing to the `auth` endpoint. That endpoint does
|
||||
initial preparations and then re-directs the user to an external
|
||||
authenticator, still inside the popup.
|
||||
3. The authenticator validates the user and returns the result of the validation
|
||||
(success OR failure), to the wrapper's endpoint (`handler/frame`).
|
||||
4. The `handler/frame` rendered webpage will issue the appropriate response to
|
||||
the webpage that opened the popup window, and the popup is closed.
|
||||
5. The user signs out by clicking on a UI interface and the webpage makes a
|
||||
request to logout the user.
|
||||
|
||||
## Implementing Your Own Auth Wrapper
|
||||
|
||||
The core interface of any auth wrapper is the `AuthProviderRouteHandlers`
|
||||
interface. This interface has four methods corresponding to the API described in
|
||||
the initial section. Any auth wrapper will have to implement this interface.
|
||||
|
||||
When initiating a login, a pop-up window is created by the frontend, to allow
|
||||
the user to initiate a login. This login request is done to the `/start`
|
||||
endpoint which is handled by the `start` method.
|
||||
|
||||
The `start` method re-directs to the external auth provider who authenticates
|
||||
the request and re-directs the request to the `/frame/handler` endpoint, which
|
||||
is handled by the `frameHandler` method.
|
||||
|
||||
The `frameHandler` returns an HTML response, containing a script that does a
|
||||
`postMessage` to the frontend window, containing the result of the request.
|
||||
The `WebMessageResponse` type is the message sent by the `postMessage` to the
|
||||
frontend.
|
||||
|
||||
A `postMessageResponse` utility function wraps the logic of generating a
|
||||
`postMessage` response that ensures that CORS is successfully handled. This
|
||||
function takes an `express.Response`, a `WebMessageResponse` and the URL of the
|
||||
frontend (`appOrigin`) as parameters and return an HTML page with the script and
|
||||
the message.
|
||||
|
||||
There is a helper class for [OAuth2](https://oauth.net/2/) based authentication providers, [OAuthAdapter](../reference/plugin-auth-backend.oauthadapter.md). This class implements the `AuthProviderRouteHandlers` interface
|
||||
for you, and instead requires you to implement [OAuthHandlers](../reference/plugin-auth-backend.oauthhandlers.md), which
|
||||
is significantly easier.
|
||||
|
||||
### Auth Environment Separation
|
||||
|
||||
The concept of an `env` is core to the way the auth backend works. It uses an
|
||||
`env` query parameter to identify the environment in which the application is
|
||||
running (`development`, `staging`, `production`, etc). Each runtime can
|
||||
simultaneously support multiple environments at the same time and the right
|
||||
handler for each request is identified and dispatched to, based on the `env`
|
||||
parameter.
|
||||
|
||||
`OAuthEnvironmentHandler` is a utility wrapper for an `OAuthHandlers` that
|
||||
implements the `AuthProviderRouteHandlers` interface while supporting multiple
|
||||
`env`s.
|
||||
|
||||
To instantiate OAuth providers (the same but for different environments), use
|
||||
`OAuthEnvironmentHandler.mapConfig`. It's a helper to iterate over a
|
||||
configuration object that is a map of environments to configurations. See one of
|
||||
the existing OAuth providers for an example of how it is used.
|
||||
|
||||
Given the following configuration:
|
||||
|
||||
```yaml
|
||||
development:
|
||||
clientId: abc
|
||||
clientSecret: secret
|
||||
production:
|
||||
clientId: xyz
|
||||
clientSecret: supersecret
|
||||
```
|
||||
|
||||
The `OAuthEnvironmentHandler.mapConfig(config, envConfig => ...)` call will
|
||||
split the config by the top level `development` and `production` keys, and pass
|
||||
on each block as `envConfig`.
|
||||
|
||||
For convenience, the `AuthProviderFactory` is a factory function that has to be
|
||||
implemented which can then generate a `AuthProviderRouteHandlers` for a given
|
||||
provider.
|
||||
|
||||
All of the supported providers provide an `AuthProviderFactory` that returns an
|
||||
`OAuthEnvironmentHandler`, capable of handling authentication for multiple
|
||||
environments.
|
||||
|
||||
## Passport
|
||||
|
||||
We chose [Passport](http://www.passportjs.org/) as our authentication platform
|
||||
@@ -46,13 +150,13 @@ plugins/auth-backend/src/providers/providerA
|
||||
**`plugins/auth-backend/src/providers/providerA/provider.ts`** defines the
|
||||
provider class which implements a handler for the chosen framework.
|
||||
|
||||
#### Adding an OAuth based provider
|
||||
### Adding an OAuth based provider
|
||||
|
||||
If we're adding an `OAuth` based provider we would implement the
|
||||
[OAuthProviderHandlers](#OAuthProviderHandlers) interface. By implementing this
|
||||
`OAuthHandlers` interface. By implementing this
|
||||
interface we can use the `OAuthProvider` class provided by `lib/oauth`, meaning
|
||||
we don't need to implement the full
|
||||
[AuthProviderRouteHandlers](#AuthProviderRouteHandlers) interface that providers
|
||||
`AuthProviderRouteHandlers` interface that providers
|
||||
otherwise need to implement.
|
||||
|
||||
The provider class takes the provider's options as a class parameter. It also
|
||||
@@ -65,7 +169,7 @@ export type ProviderAProviderOptions = OAuthProviderOptions & {
|
||||
// extra options here
|
||||
}
|
||||
|
||||
export class ProviderAAuthProvider implements OAuthProviderHandlers {
|
||||
export class ProviderAAuthProvider implements OAuthHandlers {
|
||||
private readonly _strategy: ProviderAStrategy;
|
||||
|
||||
constructor(options: ProviderAProviderOptions) {
|
||||
@@ -87,13 +191,10 @@ export class ProviderAAuthProvider implements OAuthProviderHandlers {
|
||||
}
|
||||
```
|
||||
|
||||
#### Adding an non-OAuth based provider
|
||||
|
||||
_**Note**: We have prioritized OAuth-based providers and non-OAuth providers
|
||||
should be considered experimental._
|
||||
### Adding an non-OAuth based provider
|
||||
|
||||
An non-`OAuth` based provider could implement
|
||||
[AuthProviderRouteHandlers](#AuthProviderRouteHandlers) instead.
|
||||
`AuthProviderRouteHandlers` instead.
|
||||
|
||||
```ts
|
||||
type ProviderAOptions = {
|
||||
@@ -119,13 +220,19 @@ export class ProviderAAuthProvider implements AuthProviderRouteHandlers {
|
||||
}
|
||||
```
|
||||
|
||||
#### Factory function
|
||||
#### Integration Wrapper
|
||||
|
||||
Each provider exports a factory function that instantiates the provider. The
|
||||
factory should implement [AuthProviderFactory](#AuthProviderFactory), which
|
||||
Each provider exports an object that provides a way to create new instances
|
||||
of the provider, along with related utilities like predefined sign-in resolvers.
|
||||
|
||||
The object is created using `createAuthProviderIntegration`, with the most
|
||||
important part being the `create` method that acts as the factory function
|
||||
for our provider.
|
||||
|
||||
The factory should return an implementation of `AuthProviderFactory`, which
|
||||
passes in a object with utilities for configuration, logging, token issuing,
|
||||
etc. The factory should return an implementation of
|
||||
[AuthProviderRouteHandlers](#AuthProviderRouteHandlers).
|
||||
`AuthProviderRouteHandlers`.
|
||||
|
||||
The factory is what decides the mapping from
|
||||
[static configuration](../conf/index.md) to the creation of auth providers. For
|
||||
@@ -133,48 +240,70 @@ example, OAuth providers use `OAuthEnvironmentHandler` to allow for multiple
|
||||
different configurations, one for each environment, which looks like this;
|
||||
|
||||
```ts
|
||||
export const createOktaProvider: AuthProviderFactory = ({
|
||||
globalConfig,
|
||||
config,
|
||||
tokenIssuer,
|
||||
}) =>
|
||||
OAuthEnvironmentHandler.mapConfig(config, envConfig => {
|
||||
// read options from config
|
||||
const clientId = envConfig.getString('clientId');
|
||||
const clientSecret = envConfig.getString('clientSecret');
|
||||
export const okta = 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>;
|
||||
|
||||
// instantiate our OAuthProviderHandlers implementation
|
||||
const provider = new OktaAuthProvider({
|
||||
audience,
|
||||
clientId,
|
||||
clientSecret,
|
||||
callbackUrl,
|
||||
});
|
||||
/**
|
||||
* 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 => {
|
||||
// read options from config
|
||||
const clientId = envConfig.getString('clientId');
|
||||
const clientSecret = envConfig.getString('clientSecret');
|
||||
|
||||
// Wrap the OAuthProviderHandlers with OAuthProvider, which implements AuthProviderRouteHandlers
|
||||
return OAuthProvider.fromConfig(globalConfig, provider, {
|
||||
providerId,
|
||||
tokenIssuer,
|
||||
});
|
||||
});
|
||||
// Use provided auth handler, or create a default one
|
||||
const authHandler: AuthHandler<OAuthResult> = options?.authHandler
|
||||
? options.authHandler
|
||||
: async ({ fullProfile, params }) => ({
|
||||
profile: makeProfileInfo(fullProfile, params.id_token),
|
||||
});
|
||||
|
||||
// instantiate our OAuthHandlers implementation
|
||||
const provider = new OktaAuthProvider({
|
||||
audience,
|
||||
clientId,
|
||||
clientSecret,
|
||||
callbackUrl,
|
||||
authHandler,
|
||||
signInResolver: options?.signIn?.resolver,
|
||||
resolverContext,
|
||||
});
|
||||
|
||||
// Wrap the OAuthHandlers with OAuthProvider, which implements AuthProviderRouteHandlers
|
||||
return OAuthProvider.fromConfig(globalConfig, provider, {
|
||||
providerId,
|
||||
tokenIssuer,
|
||||
});
|
||||
});
|
||||
},
|
||||
resolvers: {
|
||||
/**
|
||||
* Looks up the user by matching their email local part to the entity name.
|
||||
*/
|
||||
emailLocalPartMatchingUserEntityName: () => commonByEmailLocalPartResolver,
|
||||
|
||||
// ... additional predefined resolvers
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
The purpose of the different environments is to allow for a single auth-backend
|
||||
to serve as the authentication service for multiple different frontend
|
||||
environments, such as local development, staging, and production.
|
||||
|
||||
The factory function for other providers can be a lot simpler, as they might not
|
||||
have configuration for each environment. Looking something like this:
|
||||
|
||||
```ts
|
||||
export const createProviderAProvider: AuthProviderFactory = ({ config }) => {
|
||||
const a = config.getString('a');
|
||||
const b = config.getString('b');
|
||||
|
||||
return new ProviderAAuthProvider({ a, b });
|
||||
};
|
||||
```
|
||||
|
||||
#### Verify Callback
|
||||
|
||||
> Strategies require what is known as a verify callback. The purpose of a verify
|
||||
@@ -202,7 +331,7 @@ export { createProviderAProvider } from './provider';
|
||||
|
||||
**`plugins/auth-backend/src/providers/factories.ts`** When the `auth-backend`
|
||||
starts it sets up routing for all the available providers by calling
|
||||
`createAuthProviderRouter` on each provider. You need to import the factory
|
||||
the factory function of each provider. You need to import the factory
|
||||
function from the provider and add it to the factory:
|
||||
|
||||
```ts
|
||||
@@ -232,51 +361,3 @@ You can `curl -i localhost:7007/api/auth/providerA/start` and which should
|
||||
provide a `302` redirect with a `Location` header. Paste the URL from that
|
||||
header into a web browser and you should be able to trigger the authorization
|
||||
flow.
|
||||
|
||||
---
|
||||
|
||||
##### OAuthProviderHandlers
|
||||
|
||||
```ts
|
||||
export interface OAuthProviderHandlers {
|
||||
start(
|
||||
req: express.Request,
|
||||
options: Record<string, string>,
|
||||
): Promise<RedirectInfo>;
|
||||
handler(req: express.Request): Promise<{
|
||||
response: AuthResponse<OAuthProviderInfo>;
|
||||
refreshToken?: string;
|
||||
}>;
|
||||
refresh?(
|
||||
refreshToken: string,
|
||||
scope: string,
|
||||
): Promise<AuthResponse<OAuthProviderInfo>>;
|
||||
logout?(): Promise<void>;
|
||||
}
|
||||
```
|
||||
|
||||
##### AuthProviderRouteHandlers
|
||||
|
||||
```ts
|
||||
export interface AuthProviderRouteHandlers {
|
||||
start(req: express.Request, res: express.Response): Promise<any>;
|
||||
frameHandler(req: express.Request, res: express.Response): Promise<any>;
|
||||
refresh?(req: express.Request, res: express.Response): Promise<any>;
|
||||
logout(req: express.Request, res: express.Response): Promise<any>;
|
||||
}
|
||||
```
|
||||
|
||||
##### AuthProviderFactory
|
||||
|
||||
```ts
|
||||
export type AuthProviderFactoryOptions = {
|
||||
globalConfig: AuthProviderConfig;
|
||||
config: Config;
|
||||
logger: Logger;
|
||||
tokenIssuer: TokenIssuer;
|
||||
};
|
||||
|
||||
export type AuthProviderFactory = (
|
||||
options: AuthProviderFactoryOptions,
|
||||
) => AuthProviderRouteHandlers;
|
||||
```
|
||||
|
||||
@@ -1,206 +0,0 @@
|
||||
---
|
||||
id: auth-backend-classes
|
||||
title: Auth backend classes
|
||||
description: Documentation on Auth backend classes
|
||||
---
|
||||
|
||||
## How Does Authentication Work?
|
||||
|
||||
The Backstage application can use various external authentication providers for
|
||||
authentication. An external provider is wrapped using an
|
||||
`AuthProviderRouteHandlers` interface for handling authentication. This
|
||||
interface consists of four methods. Each of these methods is hosted at an
|
||||
endpoint (by default) `/api/auth/[provider]/method`, where `method` performs a
|
||||
certain operation as follows:
|
||||
|
||||
```
|
||||
/auth/[provider]/start -> Initiate a login from the web page
|
||||
/auth/[provider]/handler/frame -> Handle a finished authentication operation
|
||||
/auth/[provider]/refresh -> Refresh the validity of a login
|
||||
/auth/[provider]/logout -> Log out a logged-in user
|
||||
```
|
||||
|
||||
The flow is as follows:
|
||||
|
||||
1. A user attempts to sign in.
|
||||
2. A popup window is opened, pointing to the `auth` endpoint. That endpoint does
|
||||
initial preparations and then re-directs the user to an external
|
||||
authenticator, still inside the popup.
|
||||
3. The authenticator validates the user and returns the result of the validation
|
||||
(success OR failure), to the wrapper's endpoint (`handler/frame`).
|
||||
4. The `handler/frame` rendered b´webpage will issue the appropriate response to
|
||||
the webpage that opened the popup window, and the popup is closed.
|
||||
5. The user signs out by clicking on a UI interface and the webpage makes a
|
||||
request to logout the user.
|
||||
|
||||
There are currently two different classes for two authentication mechanisms that
|
||||
implement this interface: an `OAuthAdapter` for [OAuth](https://oauth.net/2/)
|
||||
based mechanisms and a `SAMLAuthProvider` for
|
||||
[SAML](http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0.html).
|
||||
|
||||
If you do not have an `OAuth2` or `SAML` based authentication provider, look in
|
||||
the section [below](#implementing-your-own-auth-wrapper).
|
||||
|
||||
### OAuth Mechanisms
|
||||
|
||||
For more information on how these methods are used and for which purpose, refer
|
||||
to the [OAuth documentation](oauth.md).
|
||||
|
||||
Currently OAuth is assumed to be the de facto authentication mechanism for
|
||||
Backstage based applications.
|
||||
|
||||
Backstage comes with a "batteries-included" set of supported commonly used OAuth
|
||||
providers: Okta, GitHub, Google, GitLab, and a generic OAuth2 provider. For a
|
||||
list of available providers, look at the available wrappers in
|
||||
`backstage/plugins/auth-backend/src/providers/`.
|
||||
|
||||
All of these use the **authorization flow** of OAuth2 to implement
|
||||
authentication.
|
||||
|
||||
If your authentication provider is any of the above mentioned providers, you can
|
||||
configure them by setting the right variables in `app-config.yaml` under the
|
||||
`auth` section.
|
||||
|
||||
### SAML
|
||||
|
||||
The SAML Provider is currently under development. Additional validation and
|
||||
profile handling is still required before use in production.
|
||||
|
||||
To configure the SAML Auth provider, look at the configuration parameters
|
||||
supported by
|
||||
[Passport-SAML](https://github.com/node-saml/passport-saml#config-parameter-details)
|
||||
under the `auth.providers.saml` key
|
||||
|
||||
For security reasons, validate that the response from the IdP is indeed signed
|
||||
by also providing the `cert` configuration.
|
||||
|
||||
### Configuration
|
||||
|
||||
Each authentication provider (except SAML) needs six parameters: an OAuth client
|
||||
ID, a client secret, an authorization endpoint, a token endpoint, an optional
|
||||
list of scopes (as a string separated by spaces) that may be required by the
|
||||
OAuth2 Server to enable end-user sign-on, and an app origin. The app origin is
|
||||
the URL at which the frontend of the application is hosted, and it is read from
|
||||
the `app.baseUrl` config. This is required because the application opens a popup
|
||||
window to perform the authentication, and once the flow is completed, the popup
|
||||
window sends a `postMessage` to the frontend application to indicate the result
|
||||
of the operation. Also this URL is used to verify that authentication requests
|
||||
are coming from only this endpoint.
|
||||
|
||||
These values are configured via the `app-config.yaml` present in the root of
|
||||
your app folder.
|
||||
|
||||
```
|
||||
auth:
|
||||
providers:
|
||||
google:
|
||||
development:
|
||||
clientId: ${AUTH_GOOGLE_CLIENT_ID}
|
||||
clientSecret: ${AUTH_GOOGLE_CLIENT_SECRET}
|
||||
github:
|
||||
development:
|
||||
clientId: ${AUTH_GITHUB_CLIENT_ID}
|
||||
clientSecret: ${AUTH_GITHUB_CLIENT_SECRET}
|
||||
enterpriseInstanceUrl: ${AUTH_GITHUB_ENTERPRISE_INSTANCE_URL}
|
||||
gitlab:
|
||||
development:
|
||||
clientId: ${AUTH_GITLAB_CLIENT_ID}
|
||||
oauth2:
|
||||
development:
|
||||
clientId: ${AUTH_OAUTH2_CLIENT_ID}
|
||||
clientSecret: ${AUTH_OAUTH2_CLIENT_SECRET}
|
||||
authorizationUrl: ${AUTH_OAUTH2_AUTH_URL}
|
||||
tokenUrl: ${AUTH_OAUTH2_TOKEN_URL}
|
||||
scope: ${AUTH_OAUTH2_SCOPE}
|
||||
saml:
|
||||
entryPoint: ${AUTH_SAML_ENTRY_POINT}
|
||||
issuer: ${AUTH_SAML_ISSUER}
|
||||
...
|
||||
```
|
||||
|
||||
## Implementing Your Own Auth Wrapper
|
||||
|
||||
The core interface of any auth wrapper is the `AuthProviderRouteHandlers`
|
||||
interface. This interface has four methods corresponding to the API described in
|
||||
the initial section. Any auth wrapper will have to implement this interface.
|
||||
|
||||
When initiating a login, a pop-up window is created by the frontend, to allow
|
||||
the user to initiate a login. This login request is done to the `/start`
|
||||
endpoint which is handled by the `start` method.
|
||||
|
||||
The `start` method re-directs to the external auth provider who authenticates
|
||||
the request and re-directs the request to the `/frame/handler` endpoint, which
|
||||
is handled by the `frameHandler` method.
|
||||
|
||||
The `frameHandler` returns an HTML response, containing a script that does a
|
||||
`postMessage` to the frontend's window, containing the result of the request.
|
||||
The `WebMessageResponse` type is the message sent by the `postMessage` to the
|
||||
frontend.
|
||||
|
||||
A `postMessageResponse` utility function wraps the logic of generating a
|
||||
`postMessage` response that ensures that CORS is successfully handled. This
|
||||
function takes an `express.Response`, a `WebMessageResponse` and the URL of the
|
||||
frontend (`appOrigin`) as parameters and return an HTML page with the script and
|
||||
the message.
|
||||
|
||||
### OAuth Wrapping Interfaces.
|
||||
|
||||
Each OAuth external provider is supported by a corresponding
|
||||
[Passport](https://github.com/jaredhanson/passport) strategy. For a generic
|
||||
OAuth2 provider, passport has a `passport-oauth2` strategy. The strategy class
|
||||
handles the implementation details of working with each provider.
|
||||
|
||||
Each strategy is wrapped by an `OAuthHandlers` interface.
|
||||
|
||||
This interface cannot be directly used as an Express HTTP request handler. To do
|
||||
so, `OAuthHandlers` are wrapped in an `OAuthAdapter`, which implements the
|
||||
`AuthProviderRouterHandlers` interface.
|
||||
|
||||
#### Env
|
||||
|
||||
The concept of an `env` is core to the way the auth backend works. It uses an
|
||||
`env` query parameter to identify the environment in which the application is
|
||||
running (`development`, `staging`, `production`, etc). Each runtime can
|
||||
simultaneously support multiple environments at the same time and the right
|
||||
handler for each request is identified and dispatched to, based on the `env`
|
||||
parameter.
|
||||
|
||||
`OAuthEnvironmentHandler` is a utility wrapper for an `OAuthHandlers` that
|
||||
implements the `AuthProviderRouteHandlers` interface while supporting multiple
|
||||
`env`s.
|
||||
|
||||
To instantiate OAuth providers (the same but for different environments), use
|
||||
`OAuthEnvironmentHandler.mapConfig`. It's a helper to iterate over a
|
||||
configuration object that is a map of environments to configurations. See one of
|
||||
the existing OAuth providers for an example of how it is used.
|
||||
|
||||
Given the following configuration:
|
||||
|
||||
```yaml
|
||||
development:
|
||||
clientId: abc
|
||||
clientSecret: secret
|
||||
production:
|
||||
clientId: xyz
|
||||
clientSecret: supersecret
|
||||
```
|
||||
|
||||
The `OAuthEnvironmentHandler.mapConfig(config, envConfig => ...)` call will
|
||||
split the config by the top level `development` and `production` keys, and pass
|
||||
on each block as `envConfig`.
|
||||
|
||||
For convenience, the `AuthProviderFactory` is a factory function that has to be
|
||||
implemented which can then generate a `AuthProviderRouteHandlers` for a given
|
||||
provider.
|
||||
|
||||
All of the supported providers provide an `AuthProviderFactory` that returns an
|
||||
`OAuthEnvironmentHandler`, capable of handling authentication for multiple
|
||||
environments.
|
||||
|
||||
### OAuth2 Provider
|
||||
|
||||
The `oauth2` provider abstracts a generic **OAuth2 + OIDC** based authentication
|
||||
provider. What this means is that after the application has been given
|
||||
permission by the user, the `authorization code` will be exchanged for an
|
||||
`access_token`, a `refresh_token` and an `id_token`. This `id_token` is used to
|
||||
obtain an email id of the user, which is then used for creating the session.
|
||||
Reference in New Issue
Block a user