npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

cidaas-interceptor-nodejs

v4.2.4

Published

[cidaas](https://www.cidaas.com) is a fast and secure Cloud Identity & Access Management solution that standardises what’s important and simplifies what’s complex. The cidaas feature set includes: - Single Sign On (SSO) based on OAuth 2.0, OpenID Connect,

Downloads

493

Readme

About cidaas:

cidaas is a fast and secure Cloud Identity & Access Management solution that standardises what’s important and simplifies what’s complex. The cidaas feature set includes:

  • Single Sign On (SSO) based on OAuth 2.0, OpenID Connect, SAML 2.0
  • Multi-Factor-Authentication with more than 14 authentication methods, including TOTP and FIDO2
  • Passwordless Authentication
  • Social Login (e.g. Facebook, Google, LinkedIn and more) as well as Enterprise Identity Provider (e.g. SAML or AD)
  • Security in Machine-to-Machine (M2M) and IoT

Installation

npm install cidaas-interceptor-nodejs --save

Check your package.json to verify the changes.

Breaking Changes

Since version 4.0.0 please make sure that you are not cross-validating tokens from different domains pointing to the same cidaas instance. By design, it should not be possible to validate tokens which were issued by the same instance from domain A against domain B. This was possible earlier when pointing to the same cidaas instance with different CNames and running the interceptor in local mode only.

Instead of using interceptorConfig.use_local_validation & interceptorConfig.use_local_validation_async in the global interceptorconfiguration, we introduced the validation_procedure property. With this it is now more easy to switch between the three different validation procedures: offline, bulk_introspect & introspect. See Configuration for more detailed information. It is still possible to overwrite this behaviour per route like before Options

Usage

Cidaas Interceptor can be used in Express or Fastify

||Introspect|Local| |-|---------|-----| |Authorization of scopes|Yes|Yes| |Authorization of roles|Yes|Yes| |Authorization of groups|Yes|No|

More information about this table can be found at the advanced section

Configuration

The configuration of the interceptor will be same for Express and Fastify

import { CidaasInterceptor, CidaasInterceptorConfig } from "cidaas-interceptor-nodejs";

let interceptorConfig = new CidaasInterceptorConfig();

// add your cidaas base url to dicover the urls for you. It will internally discover the URL from <cidaas-base-url>/.well-known/openid-configuration
interceptorConfig.baseUrl = "https://<cidaas-base-url>";
// The tenantKey of your cidaas instance 
interceptorConfig.tenantKey = "your-tenantkey";
// The key path to the keyfile used to decrypt a JWE token. Only needed if a JWE token is expected
interceptorConfig.privateKeyPath = "";
// If a JWE token is expected, but there is no privateKeyPath which can be configured, the private key needed to decrypt the token needs to be given here
interceptorConfig.privateKey = "";
// Configure client_id and client_secret, This client must be a non-interactive client 
interceptorConfig.client_id = "your client id";
interceptorConfig.client_secret = "your client secret";
/** 
 * The validation procedure to be used globally for all routes. Can be overwritten by the more specific CidaasOptions configurable for each route. 
 *   Set to 'offline' per default - here the server will check the token signature, expiry_time, baseUrl, scopes & roles. This is the fastest method available.
 *   Note: It is not entirely offline, as the service will need to fetch the JWKs to be able to validate the token signatures. 
 *   
 *   When set to 'bulk_introspect', a local validation will be executed, but the token will be stored in a list, which will be periodically sent to cidaas to validate. 
 *   This validation is done async and the interceptor will not wait for the result. Because of this, this is as fast as the offline mode.
 *   But it also means it will not have any impact on the access decision - if the introspect validation in the backend fails, access has already been granted.
 *   It will however give insights into the usage of the tokens, which will be used by the fraud detection system if enabled.
 *   
 *   'introspect' executes a real-time check and queries the Backend System, so it is the most secure check which can be executed.
 *   This check can also catch revoked access tokens. But as it needs to query cidaas and wait for the result, it is also the slowest option available.
 */
interceptorConfig.validation_procedure = "offline";

//Create the cidaas interceptor with the config
cidaas_interceptor = new CidaasInterceptor(interceptorConfig);

//Or update its config later
cidaas_interceptor.setConfig(interceptorConfig);

Express js

var express = require('express');
var app = express();
var bodyParser = require("body-parser");
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({
        extended: true
    })
);

Check Scope

app.get("/serviceurl", cidaas_interceptor.checkAccess({ scopes: ["cidaas:write"] }), function (req, res) {

// your code

});

Check Role

app.post("/serviceurl", cidaas_interceptor.checkAccess({ roles: ["Admin"] }), function (req, res) {

// your code

});

Check Group

app.post("/serviceurl", cidaas_interceptor.checkAccess({ groups: [{groupId : "mygroup"}]}), function (req, res) {

// your code

});

Check Role and Scope

app.get("/serviceurl", cidaas_interceptor.checkAccess({ scopes: ["cidaas:write"], roles: ["Admin"] }), function (req, res) {

// your code

});

DenyAll

app.get("/serviceurl", cidaas_interceptor.checkAccess({denyAll : true}), function (req, res) {

// your code

});

PermitAll

app.get("/serviceurl", cidaas_interceptor.checkAccess({permitAll : true}), function (req, res) {
 
// your code
 
});

Or just ignore the inceptor code

app.get("/serviceurl", function (req, res) {
 
// your code
 
});

Fastify

In Fastify, you have to register your routes to an express router.

const router = require('express').Router()
    router.get("/write", async (request: any, reply: any) => {
      reply.status(StatusCodes.OK).send({ status: "success" }
    )})
    router.get("/delete", async (request: any, reply: any) => {
        reply.status(StatusCodes.OK).send({ status: "success" }
    )})

Then register fastify-express and then add the interceptorOptions to your routes. This allows for different accessConfigurations for each route.

var fInstance = require("fastify")
await fInstance.register(require('fastify-express'))
.after(() => {
    fastify.use(
      "/write",
      cidaas_interceptor.checkAccess({
          scopes: ["write"],
          use_local_validation : true,
          interceptorConfig: interceptorConfig
      }))
    fastify.use(
        "/delete",
        cidaas_interceptor.checkAccess({
            scopes: ["delete"],
            interceptorConfig: interceptorConfig
      }))
    fastify.use(router)
})

Complete server.js example with configuration:

const fastify = require("fastify")({
  logger: true
});

let interceptorConfig = new CidaasInterceptorConfig();

// Add your cidaas base url to dicover the urls for you. It will internally discover the URL from <cidaas-base-url>/.well-known/openid-configuration
interceptorConfig.baseUrl = "https://<cidaas-base-url>";

 // use_local_validation : enables the offline token validation, which will improve performance.
interceptorConfig.use_local_validation = true; 

// use_local_validation_async: enables the transfer of locally validated tokens to the bulk-introspection endpoint
interceptorConfig.use_local_validation_async = true; 

//Create the cidaas interceptor with the config
global.cidaas_interceptor = new CidaasInterceptor(interceptorConfig);

//Or update its config later
global.cidaas_interceptor.setConfig(interceptorConfig);

//declare  routes on express router
const router = require('express').Router()
    router.get("/write", async (request: any, reply: any) => {
      reply.status(StatusCodes.OK).send({ status: "success" }
    )})
    router.get("/delete", async (request: any, reply: any) => {
        reply.status(StatusCodes.OK).send({ status: "success" }
    )})

// instantiate fastify
var fInstance = require("fastify")

//register fastify-express plugin and add interceptorOptions to the routes
await fInstance.register(require('fastify-express'))
.after(() => {
    fastify.use(
      "/write",
      cidaas_interceptor.checkAccess({
          scopes: ["write"],
          use_local_validation : true,
          interceptorConfig: interceptorConfig
      }))
    fastify.use(
        "/delete",
        cidaas_interceptor.checkAccess({
            scopes: ["delete"],
            interceptorConfig: interceptorConfig
      }))
    fastify.use(router)
})

// Run the server!
fastify.listen(3000, function(err: any, address: any) {
  if (err) {
    fastify.log.error(err);
    process.exit(1);
  }
  fastify.log.info(`server listening on ${address}`);
});

The usage of the parameters for the fastfy interceptor are exactly the same as with the express examples

Advanced

Config

The interceptorconfig contains the basic information for the interceptor to work. The interceptorconfig can contain the following options:

| Key | Description | Default | Required | | ------------- |:-------------|:-------------:| :-----:| | base_url | The base URL of the cidaas instance. | - | Yes | |tenantkey|The tenantkey of the cidaas instance.|-|Yes | | privateKeyPath | This property is needed if the use_local_validation property is set to true in order to decrypt a JWE token. Here the path to the keyfile has to be given.| - | Depending on validation procedure | |privateKey|This property is needed if the use_local_validation property is set to true in order to decrypt a JWE token if privateKeyPath is not set. Here a key has to be given.| - | Depending on validation procedure | | validation_procedure | The validation procedure to use. Either 'offline', 'bulk_introspect' or 'introspect'| offline | No |

Options

The interceptor options can be different for each route. The interceptor options can contain the following keys:

| Key | Description | Default | Required | | ------------- |:-------------|:-------------:| :-----:| | interceptorConfig | The base URL of the cidaas instance. | null | Yes | | use_local_validation |If set to true, the interceptor will validate locally. Local mode will check the signature, expiry time, scopes, roles. If set to false, the interceptor will validate with Introspect. Introspect will perform an online validation which checks if the token is in the DB of cidaas, expiry time, scopes, roles and groups.|false|No| | use_local_validation_async |If set to true, the interceptor will validate locally with an async bulk_introspect. Bulk_introspect will perform the offline validation and stores the requested access tokens in a cache. Periodically, a part the of requests will be sent to cidaas for the fraud detection. Requires use_local_validation to be true|false|No| | roles |Defines the roles that the interceptor will check for in the token.| - |No| | scopes |Defines the scopes that the interceptor will check for in the token.| - | No | | groups |Defines the groups that the interceptor will check for in the token.| - | No | | strictScopeValidation | Please check this section. | false | No | | strictRoleValidation | Please check this section. | false | No | | strictGroupValidation | Please check this section. | false | No | | strictValidation | Please check this section. | false | No | | denyAll | Denies access to this route no matter which authorization. | false | No | | permitAll | Allows access to this route no matter which authentication.| false | No |

Further explanation about the strict validation feature:
  • strictValidation, if true at least one scope, role and group of the access_token has to match your annotations.
  • strictScopeValidation, if true all scopes of the access_token have to match your annotations.
  • strictRoleValidation, if true at all roles of the access_token have to match your annotations.
  • strictGroupValidation, if true at all groups of the access_token have to match your annotations.
  • if none of these is set and at least one type is given, at least one scope, role, group of the access_token has to match your annotations.
  • if no scopes, roles and groups annotations are given no further checks will be performed except validity and expiry time of the token.

Note:
If an anonymous (client credential grant) token is passed to an API which is secured by strict validation which requires scopes, roles and groups, only the scopes will be matched. For any client credential grant token, there is no user who could be part of any group or who has any role set.
This way it is possible to secure the same API by user roles, groups and scopes and still be able to consume it with any backend server which does have the required scopes.

custom group validation

Make sure to set the interceptor to online / introspect mode, if you want to validate against custom groups.

For validating groups, the following entity can be passed as an array to specify the groups check:

GroupValidationEntity {
    groupId: string;
    groupType: string;
    roles: string[];
    strictRoleValidation: boolean;
    strictValidation: boolean;
}

Check Role in custom group

app.post("/serviceurl", cidaas_interceptor.checkAccess({ groups: [{groupId : "mygroup", roles: ["Admin"]}]}), function (req, res) {

// your code

});

When strictRoleValidation is enabled for a group check, the token has to have all specified roles in the group. Also, the groupId and the groupType have to be specified in the interceptoroptions

app.post("/serviceurl", cidaas_interceptor.checkAccess(
       {
         groups: [{
           groupId : "mygroup",
           groupType : "customers", // The groupType can be applied to any cidaas group. For more info, see in the cidaas docs.
           roles : ["myrole1","myrole2"]
           strictValidation : true, // The given groupId 'mygroup' must be of type "customers"
           strictRoleValidation: true // The user must have 'myrole1' & 'myrole2' inside the group 'mygroup' to get access.
       },
       {
           groupId : "secondgroup",
           roles : ["myrole1"]
       }],
         strictGroupValidation: true // Both group validations must be successful to get access. If false, if either of the group validations is succeful the user will get access
       }), function (req, res) {

// your code

});