The OIDC Service is a component built using LoopBack 4 that provides OpenID Connect (OIDC) support for authentication. It allows integration with external identity providers and enables the issuance and verification of JSON Web Tokens (JWTs) using the OIDC protocol. This service provides the following features:
-
The OIDC service fully supports the OpenID Connect standard, which is an identity layer built on top of the OAuth 2.0 protocol. It allows your application to authenticate and obtain user identity information from external identity providers.
-
The OIDC service handles the authentication process, allowing users to log in to your application using their credentials from supported identity providers. It supports various authentication flows, including authorization code flow, implicit flow, and hybrid flow.
-
The OIDC service provides authorization capabilities, allowing you to control access to your application's resources based on user roles and permissions. It integrates with LoopBack 4's built-in authorization features, such as decorators and guards, to enforce fine-grained access control.
-
The OIDC service handles the generation, validation, and revocation of access tokens, refresh tokens, and ID tokens. It follows the OAuth 2.0 and OpenID Connect specifications for token-based authentication and authorization.
-
The OIDC service is designed to be extensible and customizable. You can extend its functionality by adding custom authentication and authorization providers, implementing custom token handlers, or integrating additional identity management services.
-
The OIDC service provides a developer-friendly API for integrating authentication and authorization into your application. It offers easy-to-use methods and interfaces for handling user authentication, profile management, token management, and other related tasks.
To get started with a basic implementation of this service, see /sandbox/oidc-basic-example.
-
Application Registration: Before using OIDC, you need to register your application with the identity provider (IdP) or the OIDC service. During the registration process, you typically provide information about your application, such as the redirect URLs, client ID, and client secret.
-
User Initiation: When a user wants to log in to your application, they are directed to the login page of the IdP. This can be initiated by clicking a "Sign In" button or by accessing a protected resource that requires authentication.
-
Authentication Request: Your application initiates the authentication process by redirecting the user to the IdP's authorization endpoint. The request includes parameters such as the client ID, redirect URL, requested scopes, and response type (e.g., code, token, or both).
-
User Authentication: The user enters their credentials (username and password) on the IdP's login page. The IdP verifies the user's identity and may prompt for additional factors, such as multi-factor authentication (MFA).
-
Authorization Grant: Once the user is authenticated, the IdP generates an authorization grant. The type of grant depends on the requested response type. For example, in the authorization code flow, the grant is a short-lived authorization code returned to the client as a query parameter in the redirect URL.
-
Token Request: The client application (your application) exchanges the authorization grant for an access token and optionally a refresh token. The client makes a POST request to the IdP's token endpoint, providing the authorization grant, client ID, client secret, and other required parameters.
-
Token Validation: The IdP validates the authorization grant and, if valid, issues an access token and refresh token. The access token contains information about the user and their authorized scopes. The client can use the access token to access protected resources on behalf of the user.
-
User Info Request: To obtain additional information about the user, the client can make a request to the IdP's user info endpoint, providing the access token as an authorization header or query parameter. The user info response contains user attributes and claims, such as name, email, and profile picture.
-
Token Usage: The client application can use the access token to make authorized requests to the protected resources of your application's API. The access token is typically included as an authorization header or a query parameter in API requests.
Note: The OIDC flow may vary depending on the specific flow you choose (e.g., authorization code flow, implicit flow, hybrid flow) and the configurations of the IdP and client application. However, the general principles and steps outlined above provide an overview of the OIDC working and flow.
npm i @sourceloop/oidc-service
To use the OIDC Service in your LoopBack 4 application, follow these steps:
- Create a new LoopBack 4 application if you don't have one already:
lb4 testapp
- Install the OIDC service:
npm i @sourceloop/oidc-service
- Set the required environment variables.
- The .env variables
OIDC_CLAIMS_PROFILE
,OIDC_ISSUER_URL
to set the common claims and issuer url for all the clients. - Run the migrations.
- Make sure you have entries for
client_id
,client_secret
,grant-types
,redirect-urls
,response_types
in yourauth_clients
table. - Set up a Loopback4 Datasource with
dataSourceName
property set toAuthDbSourceName
. You can see an example datasource here. - Set up a Loopback4 Datasource for caching tokens with
dataSourceName
property set toAuthCacheSourceName
. - Add the OIDCServiceComponent to your LoopBack 4 application in the application.ts file:
import {ApplicationConfig} from '@loopback/core';
import {RestApplication} from '@loopback/rest';
import {OidcServiceComponent, TemplateBindings} from '@sourceloop/oidc-service';
import path from 'path';
export {ApplicationConfig};
export class OidcApplication extends RestApplication {
constructor(options: ApplicationConfig = {}) {
super(options);
// ...
// Add the OidcServiceComponent to the application
this.component(OidcServiceComponent);
// Modify the template file path for login and interaction screens
this.bind(TemplateBindings.LoginTemplate).to(
path.join(__dirname, '../public/views/login.ejs'),
);
this.bind(TemplateBindings.InteractionTemplate).to(
path.join(__dirname, '../public/views/interaction.ejs'),
);
// ...
}
}
Name | Required | Default Value | Description |
---|---|---|---|
NODE_ENV | Yes | Node environment value, i.e. 'dev', 'test', 'prod' | |
LOG_LEVEL | Yes | Log level value, i.e. 'error', 'warn', 'info', 'verbose', 'debug' | |
DB_HOST | Yes | Hostname for the database server. | |
DB_PORT | Yes | Port for the database server. | |
DB_USER | Yes | User for the database. | |
DB_PASSWORD | Yes | Password for the database user. | |
DB_DATABASE | Yes | Database to connect to on the database server. | |
DB_SCHEMA | Yes | public | Database schema used for the data source. In PostgreSQL, this will be 'public' unless a schema is made explicitly for the service. |
REDIS_HOST | Yes | Hostname of the Redis server. | |
REDIS_PORT | Yes | Port to connect to the Redis server over. | |
REDIS_URL | Yes | Fully composed URL for Redis connection. Used instead of other settings if set. | |
REDIS_PASSWORD | Yes | Password for Redis if authentication is enabled. | |
REDIS_DATABASE | Yes | Database within Redis to connect to. | |
JWT_PRIVATE_KEY | Yes | Asymmetric signing key of the JWT token. | |
JWT_PUBLIC_KEY | Yes | Verifying signed JWT Token. | |
JWT_SECRET | Yes | Symmetric signing key of the JWT token. | |
JWT_ISSUER | Yes | Issuer of the JWT token. | |
OIDC_CLAIMS_PROFILE | Yes | Common claims for all the clients. | |
OIDC_ISSUER_URL | Yes | Issuer URL. | |
OIDC_JWKS_KTY | Yes | Key Type. It specifies the type of the key, e.g. 'RSA'. | |
OIDC_JWKS_ALG | Yes | Algorithm, e.g. RS256. | |
OIDC_JWKS_USE | Yes | Key Use. It indicates the purpose of the key, e.g. signature. | |
OIDC_JWKS_D | Yes | Private Exponent. It represents the private exponent of the RSA key. | |
OIDC_JWKS_DP | Yes | First Factor CRT Exponent. It is the exponent used for the Chinese Remainder Theorem (CRT) calculation. | |
OIDC_JWKS_DQ | Yes | Second Factor CRT Exponent. It is another exponent used for the CRT calculation. | |
OIDC_JWKS_E | Yes | Public Exponent. It represents the public exponent of the RSA key. | |
OIDC_JWKS_N | Yes | Modulus. It is the modulus component of the RSA key. | |
OIDC_JWKS_P | Yes | First Prime Factor. It represents the first prime factor of the modulus. | |
OIDC_JWKS_Q | Yes | Second Prime Factor. It is the second prime factor of the modulus. | |
OIDC_JWKS_QI | Yes | First CRT Coefficient. It is the coefficient used for the CRT calculation. | |
OIDC_JWKS_KID | Yes | Key ID. It is an identifier for the key. | |
OIDC_COOKIES | Yes | For setting cookie key. |
Detailed description for above keys here: https://openid.net/specs/openid-connect-core-1_0.html
The migrations required for this service are processed during the installation automatically if you set the OIDC_MIGRATION
or SOURCELOOP_MIGRATION
env variable. The migrations use db-migrate
with db-migrate-pg
driver for migrations, so you will have to install these packages to use auto-migration. Please note that if you are using some pre-existing migrations or databasea, they may be affected. In such a scenario, it is advised that you copy the migration files in your project root, using the OIDC_MIGRATION_COPY
or SOURCELOOP_MIGRATION_COPY
env variables. You can customize or cherry-pick the migrations in the copied files according to your specific requirements and then apply them to the DB.
Additionally, there is now an option to choose between SQL migration or PostgreSQL migration. NOTE : For @sourceloop/cli users, this choice can be specified during the scaffolding process by selecting the "type of datasource" option.
Authorization: Bearer where is a JWT token signed using JWT issuer and secret.
Content-Type: application/json
in the response and in request if the API method is NOT GET
{version}: Defines the API Version
200: Successful Response. Response body varies w.r.t API 401: Unauthorized: The JWT token is missing or invalid 403: Forbidden : Not allowed to execute the concerned API 404: Entity Not Found 400: Bad Request (Error message varies w.r.t API) 201: No content: Empty Response
Visit the OpenAPI spec docs