diff --git a/README.md b/README.md index 47deb30..2a208d3 100644 --- a/README.md +++ b/README.md @@ -37,33 +37,40 @@ npm install nest-keycloak-connect keycloak-connect --save ### Module registration Registering the module: + ```typescript KeycloakConnectModule.register({ authServerUrl: 'http://localhost:8080', // might be http://localhost:8080/auth for older keycloak versions realm: 'master', clientId: 'my-nestjs-app', - secret: 'secret', + secret: 'secret', policyEnforcement: PolicyEnforcementMode.PERMISSIVE, // optional tokenValidation: TokenValidation.ONLINE, // optional -}) +}); ``` Async registration is also available: + ```typescript KeycloakConnectModule.registerAsync({ useExisting: KeycloakConfigService, - imports: [ConfigModule] -}) + imports: [ConfigModule], +}); ``` #### KeycloakConfigService + ```typescript import { Injectable } from '@nestjs/common'; -import { KeycloakConnectOptions, KeycloakConnectOptionsFactory, PolicyEnforcementMode, TokenValidation } from 'nest-keycloak-connect'; +import { + KeycloakConnectOptions, + KeycloakConnectOptionsFactory, + PolicyEnforcementMode, + TokenValidation, +} from 'nest-keycloak-connect'; @Injectable() export class KeycloakConfigService implements KeycloakConnectOptionsFactory { - createKeycloakConnectOptions(): KeycloakConnectOptions { return { authServerUrl: 'http://localhost:8080', // might be http://localhost:8080/auth for older keycloak versions @@ -73,7 +80,7 @@ export class KeycloakConfigService implements KeycloakConnectOptionsFactory { policyEnforcement: PolicyEnforcementMode.PERMISSIVE, tokenValidation: TokenValidation.ONLINE, }; - } + } } ``` @@ -83,7 +90,7 @@ You can also register by just providing the `keycloak.json` path and an optional KeycloakConnectModule.register(`./keycloak.json`, { policyEnforcement: PolicyEnforcementMode.PERMISSIVE, tokenValidation: TokenValidation.ONLINE, -}) +}); ``` ### Guards @@ -91,11 +98,13 @@ KeycloakConnectModule.register(`./keycloak.json`, { Register any of the guards either globally, or scoped in your controller. #### Global registration using APP_GUARD token -***NOTE: These are in order, see https://docs.nestjs.com/guards#binding-guards for more information.*** + +**_NOTE: These are in order, see https://docs.nestjs.com/guards#binding-guards for more information._** + ```typescript providers: [ { - provide: APP_GUARD, + provide: APP_GUARD, useClass: AuthGuard, }, { @@ -106,9 +115,11 @@ providers: [ provide: APP_GUARD, useClass: RoleGuard, }, -] +]; ``` + #### Scoped registration + ```typescript @Controller('cats') @UseGuards(AuthGuard, ResourceGuard) @@ -118,14 +129,17 @@ export class CatsController {} ## What does these providers do ? ### AuthGuard + Adds an authentication guard, you can also have it scoped if you like (using regular `@UseGuards(AuthGuard)` in your controllers). By default, it will throw a 401 unauthorized when it is unable to verify the JWT token or `Bearer` header is missing. ### ResourceGuard + Adds a resource guard, which is permissive by default (can be configured see [options](#nest-keycloak-options)). Only controllers annotated with `@Resource` and methods with `@Scopes` are handled by this guard. -***NOTE: This guard is not necessary if you are using role-based authorization exclusively. You can use role guard exclusively for that.*** +**_NOTE: This guard is not necessary if you are using role-based authorization exclusively. You can use role guard exclusively for that._** ### RoleGuard + Adds a role guard, **can only be used in conjunction with resource guard when enforcement policy is PERMISSIVE**, unless you only use role guard exclusively. Permissive by default. Used by controller methods annotated with `@Roles` (matching can be configured) @@ -134,7 +148,13 @@ Permissive by default. Used by controller methods annotated with `@Roles` (match In your controllers, simply do: ```typescript -import { Resource, Roles, Scopes, Public, RoleMatchingMode } from 'nest-keycloak-connect'; +import { + Resource, + Roles, + Scopes, + Public, + RoleMatchingMode, +} from 'nest-keycloak-connect'; import { Controller, Get, Delete, Put, Post, Param } from '@nestjs/common'; import { Product } from './product'; import { ProductService } from './product.service'; @@ -188,7 +208,7 @@ export class ProductController { Here is the decorators you can use in your controllers. | Decorator | Description | -|--------------------|-----------------------------------------------------------------------------------------------------------| +| ------------------ | --------------------------------------------------------------------------------------------------------- | | @AuthenticatedUser | Retrieves the current Keycloak logged-in user. (must be per method, unless controller is request scoped.) | | @EnforcerOptions | Keycloak enforcer options. | | @Public | Allow any user to use the route. | @@ -197,7 +217,9 @@ Here is the decorators you can use in your controllers. | @Roles | Keycloak realm/application roles. | ## Multi tenant configuration + Setting up for multi-tenant is configured as an option in your configuration: + ```typescript { authServerUrl: 'http://localhost:8180/auth', @@ -207,9 +229,13 @@ Setting up for multi-tenant is configured as an option in your configuration: realmResolver: (request) => { return request.get('host').split('.')[0]; }, - realmSecretResolver: (realm) => { + realmSecretResolver: (realm, request) => { const secrets = { master: 'secret', slave: 'password' }; return secrets[realm]; + }, + realmAuthServerUrlResolver: (realm, request) => { + const authServerUrls = { master: 'https://master.local/auth', slave: 'https://slave.local/auth' }; + return authServerUrls[realm]; } } } @@ -218,25 +244,29 @@ Setting up for multi-tenant is configured as an option in your configuration: ## Configuration options ### Keycloak Options + For Keycloak options, refer to the official [keycloak-connect](https://github.com/keycloak/keycloak-nodejs-connect/blob/main/middleware/auth-utils/config.js) library. ### Nest Keycloak Options -| Option | Description | Required | Default | -|-------------------|-------------------------------------------------------------------------------------|----------|--------------| -| cookieKey | Cookie Key | no | KEYCLOAK_JWT | -| logLevels | Built-in logger level (deprecated, will be removed in 2.0) | no | log | -| useNestLogger | Use the nest logger (deprecated, will be removed in 2.0) | no | true | -| policyEnforcement | Sets the policy enforcement mode | no | PERMISSIVE | -| tokenValidation | Sets the token validation method | no | ONLINE | -| multiTenant | Sets the options for [multi-tenant configuration](#multi-tenant-options) | no | - | -| roleMerge | Sets the merge mode for @Role decorator | no | OVERRIDE | + +| Option | Description | Required | Default | +| ----------------- | ------------------------------------------------------------------------ | -------- | ------------ | +| cookieKey | Cookie Key | no | KEYCLOAK_JWT | +| logLevels | Built-in logger level (deprecated, will be removed in 2.0) | no | log | +| useNestLogger | Use the nest logger (deprecated, will be removed in 2.0) | no | true | +| policyEnforcement | Sets the policy enforcement mode | no | PERMISSIVE | +| tokenValidation | Sets the token validation method | no | ONLINE | +| multiTenant | Sets the options for [multi-tenant configuration](#multi-tenant-options) | no | - | +| roleMerge | Sets the merge mode for @Role decorator | no | OVERRIDE | ### Multi Tenant Options -| Option | Description | Required | Default | -|---------------------|---------------------------------------------------------------------------------------------------------|----------|--------------| -| resolveAlways | Option to always resolve the realm and secret. Disabled by default. | no | false | -| realmResolver | A function that passes a request (from respective platform i.e express or fastify) and returns a string | yes | - | -| realmSecretResolver | A function that passes the realm string and returns the secret string | yes | - | + +| Option | Description | Required | Default | +| -------------------------- | ------------------------------------------------------------------------------------------------------- | -------- | ------- | +| resolveAlways | Option to always resolve the realm and secret. Disabled by default. | no | false | +| realmResolver | A function that passes a request (from respective platform i.e express or fastify) and returns a string | yes | - | +| realmSecretResolver | A function that passes the realm string, and an optional request and returns the secret string | no | - | +| realmAuthServerUrlResolver | A function that passes the realm string, and an optional request and returns the auth server url string | no | - | ## Example app