Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
nest-keycloak-connect
Advanced tools
@Resource
, @Scopes
, or @Roles
in your controllers and you're good to go.yarn add nest-keycloak-connect keycloak-connect
npm install nest-keycloak-connect keycloak-connect --save
Registering the module:
KeycloakConnectModule.register({
authServerUrl: 'http://localhost:8080', // might be http://localhost:8080/auth for older keycloak versions
realm: 'master',
clientId: 'my-nestjs-app',
secret: 'secret',
policyEnforcement: PolicyEnforcementMode.PERMISSIVE, // optional
tokenValidation: TokenValidation.ONLINE, // optional
});
Async registration is also available:
KeycloakConnectModule.registerAsync({
useExisting: KeycloakConfigService,
imports: [ConfigModule],
});
import { Injectable } from '@nestjs/common';
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
realm: 'master',
clientId: 'my-nestjs-app',
secret: 'secret',
policyEnforcement: PolicyEnforcementMode.PERMISSIVE,
tokenValidation: TokenValidation.ONLINE,
};
}
}
You can also register by just providing the keycloak.json
path and an optional module configuration:
KeycloakConnectModule.register(`./keycloak.json`, {
policyEnforcement: PolicyEnforcementMode.PERMISSIVE,
tokenValidation: TokenValidation.ONLINE,
});
Register any of the guards either globally, or scoped in your controller.
NOTE: These are in order, see https://docs.nestjs.com/guards#binding-guards for more information.
providers: [
{
provide: APP_GUARD,
useClass: AuthGuard,
},
{
provide: APP_GUARD,
useClass: ResourceGuard,
},
{
provide: APP_GUARD,
useClass: RoleGuard,
},
];
@Controller('cats')
@UseGuards(AuthGuard, ResourceGuard)
export class CatsController {}
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.
Adds a resource guard, which is permissive by default (can be configured see 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.
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)
In your controllers, simply do:
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';
@Controller()
@Resource(Product.name)
export class ProductController {
constructor(private service: ProductService) {}
@Get()
@Public()
async findAll() {
return await this.service.findAll();
}
@Get()
@Roles({ roles: ['admin', 'other'] })
async findAllBarcodes() {
return await this.service.findAllBarcodes();
}
@Get(':code')
@Scopes('View')
async findByCode(@Param('code') code: string) {
return await this.service.findByCode(code);
}
@Post()
@Scopes('Create')
async create(@Body() product: Product) {
return await this.service.create(product);
}
@Delete(':code')
@Scopes('Delete')
@Roles({ roles: ['admin', 'realm:sysadmin'], mode: RoleMatchingMode.ALL })
async deleteByCode(@Param('code') code: string) {
return await this.service.deleteByCode(code);
}
@Put(':code')
@Scopes('Edit')
async update(@Param('code') code: string, @Body() product: Product) {
return await this.service.update(code, product);
}
}
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. |
@Resource | Keycloak application resource name. |
@Scopes | Keycloak application scope name. |
@Roles | Keycloak realm/application roles. |
Setting up for multi-tenant is configured as an option in your configuration:
{
authServerUrl: 'http://localhost:8180/auth',
clientId: 'nest-api',
secret: 'fallback', // will be used as fallback when resolver returns null
multiTenant: {
realmResolver: (request) => {
return request.get('host').split('.')[0];
},
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];
}
}
}
For Keycloak options, refer to the official keycloak-connect library.
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 | no | - |
roleMerge | Sets the merge mode for @Role decorator | no | OVERRIDE |
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 | - |
An example application is provided in the source code with both Keycloak Realm and Postman requests for you to experiment with.
FAQs
keycloak-nodejs-connect module for Nest
The npm package nest-keycloak-connect receives a total of 31,744 weekly downloads. As such, nest-keycloak-connect popularity was classified as popular.
We found that nest-keycloak-connect demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.