All Projects → felixheck → Hapi Auth Keycloak

felixheck / Hapi Auth Keycloak

Licence: mit
JSON Web Token based Authentication powered by Keycloak

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to Hapi Auth Keycloak

Sjwt
Simple JWT Golang
Stars: ✭ 86 (+196.55%)
Mutual labels:  authentication, jwt, jsonwebtoken
Spring Boot Jwt
JWT auth service using Spring Boot, Spring Security and MySQL
Stars: ✭ 795 (+2641.38%)
Mutual labels:  authentication, jwt, jsonwebtoken
Djwt
Create and verify JSON Web Tokens (JWT) with deno.
Stars: ✭ 93 (+220.69%)
Mutual labels:  authentication, jwt, jsonwebtoken
Authex
Authex is an opinionated JWT authentication and authorization library for Elixir.
Stars: ✭ 73 (+151.72%)
Mutual labels:  authentication, jwt, auth
Fastify Esso
The easiest authentication plugin for Fastify, with built-in support for Single sign-on
Stars: ✭ 20 (-31.03%)
Mutual labels:  authentication, jwt, auth
Paseto
Platform-Agnostic Security Tokens implementation in GO (Golang)
Stars: ✭ 461 (+1489.66%)
Mutual labels:  authentication, jwt, auth
Django Graphql Jwt
JSON Web Token (JWT) authentication for Graphene Django
Stars: ✭ 649 (+2137.93%)
Mutual labels:  authentication, jwt, jsonwebtoken
Auth0.js
Auth0 headless browser sdk
Stars: ✭ 755 (+2503.45%)
Mutual labels:  authentication, jwt
Hasura Backend Plus
🔑Auth and 📦Storage for Hasura. The quickest way to get Auth and Storage working for your next app based on Hasura.
Stars: ✭ 776 (+2575.86%)
Mutual labels:  authentication, jwt
Keystonejs Auth
A Secure Star Wars API developed with KeystoneJS
Stars: ✭ 13 (-55.17%)
Mutual labels:  authentication, auth
Geek Framework
基于SpringBoot+Shiro+Redis+Jwt+Thymeleaf+MyBatis 开发的后台用户、角色、权限、会员管理、RestFul、Token和前台用户登录注册以及前后台用户分离的脚手架,技术交流请加QQ群:805442966
Stars: ✭ 804 (+2672.41%)
Mutual labels:  jwt, jsonwebtoken
Typescript Seed
Typescript Seed Project (Angular, Hapi, Cookie Auth, TypeORM, Postgres)
Stars: ✭ 12 (-58.62%)
Mutual labels:  hapi, authentication
X Restful Api Generator Koa
一个基于 Koa 的 RESTful API 服务脚手架。 A RESTful API generator for Koa
Stars: ✭ 18 (-37.93%)
Mutual labels:  jwt, jsonwebtoken
Aws Serverless Auth Reference App
Serverless reference app and backend API, showcasing authentication and authorization patterns using Amazon Cognito, Amazon API Gateway, AWS Lambda, and AWS IAM.
Stars: ✭ 724 (+2396.55%)
Mutual labels:  authentication, auth
Php Auth
Authentication for PHP. Simple, lightweight and secure.
Stars: ✭ 713 (+2358.62%)
Mutual labels:  authentication, auth
Access
Ponzu Addon to manage API access grants and tokens for authentication
Stars: ✭ 13 (-55.17%)
Mutual labels:  authentication, jwt
React Native Fingerprint Scanner
Provide Fingerprint, Touch ID, and Face ID Scanner for React Native (Compatible with both Android and iOS)
Stars: ✭ 704 (+2327.59%)
Mutual labels:  authentication, auth
Jsonwebtoken
JWT lib in rust
Stars: ✭ 681 (+2248.28%)
Mutual labels:  jwt, jsonwebtoken
Hzdtf.foundation.framework
基础框架系统,支持.NET和.NET Core平台,语言:C#,DB支持MySql和SqlServer,主要功能有抽象持久化、服务层,将业务基本的增删改查抽离复用;提供代码生成器从DB生成实体、持久化、服务以及MVC控制器,每层依赖接口,并需要在客户端将对应实现层用Autofac程序集依赖注入,用AOP提供日志跟踪、事务、模型验证等。对Autofac、Redis、RabbitMQ封装扩展;DB访问提供自动主从访问,Redis客户端分区。特别适合管理系统。
Stars: ✭ 22 (-24.14%)
Mutual labels:  jwt, auth
Kratos Selfservice Ui React Native
A reference implementation of an app using ORY Kratos for auth (login), sign up (registration), profile settings (update password), MFA/2FA, account recovery (password reset), and more for React Native. This repository is available as an expo template!
Stars: ✭ 24 (-17.24%)
Mutual labels:  authentication, auth

hapi-auth-keycloak

JSON Web Token based Authentication powered by Keycloak

Travis node npm standard npm Coverage Status

  1. Introduction
  2. Installation
  3. Usage
  4. API
  5. Example
  6. Migration Guides
  7. Developing and Testing
  8. Contribution

Introduction

hapi-auth-keycloak is a plugin for hapi.js which enables to protect your endpoints in a smart but professional manner using Keycloak as authentication service. It is inspired by the related express.js middleware. The plugin validates the passed Bearer token offline with a provided public key or online with help of the Keycloak server. Optionally, the successfully validated tokens and the related user data get cached using catbox. The caching enables a fast processing even though the user data don't get changed until the token expires. Furthermore it is possible to enable an api key interceptor proxying the request to an api key service which returns the temporary bearer token. It plays well with the hapi.js-integrated authentication/authorization feature. Besides the authentication strategy it is possible to validate tokens by yourself, e.g. to authenticate incoming websocket or queue messages, and to register/use multiple strategies via jscheffner/hapi-auth-any.

The modules standard and ava are used to grant a high quality implementation.

Compatibility

Major Release hapi.js version node version
v5 >=18.4 @hapi/hapi >=12
v4.1 >=18.3.1 @hapi/hapi >=8
v4 >=18 hapi >=8
v3 >=17 hapi >=8
v2 >=12 hapi >=6

Installation

For installation use npm:

$ npm install --save hapi-auth-keycloak

or clone the repository:

$ git clone https://github.com/felixheck/hapi-auth-keycloak

Usage

Import

First you have to import the module:

const authKeycloak = require("hapi-auth-keycloak");

Create hapi server

Afterwards create your hapi server if not already done:

const hapi = require("@hapi/hapi");

const server = hapi.server({ port: 8888 });

Registration

Finally register the plugin, set the correct options and the authentication strategy:

await server.register({ plugin: authKeycloak });

server.auth.strategy("keycloak-jwt", "keycloak-jwt", {
  realmUrl: "https://localhost:8080/auth/realms/testme",
  clientId: "foobar",
  minTimeBetweenJwksRequests: 15,
  cache: true,
  userInfo: ["name", "email"],
});

Route Configuration & Scope

Define your routes and add keycloak-jwt when necessary. It is possible to define the necessary scope like documented by the express.js middleware:

  • To secure an endpoint with a resource's role , use the role name (e.g. editor).
  • To secure an endpoint with another resource's role, prefix the role name (e.g. other-resource:creator)
  • To secure an endpoint with a realm role, prefix the role name with realm: (e.g. realm:admin).
  • To secure an endpoint with fine-grained scope definitions, prefix the Keycloak scopes with scope: (e.g. scope:foo.READ).
  • To secure an endpoint with a OAuth2 client scope, prefix the client scope with clientscope: (e.g. clientscope:profile).
server.route([
  {
    method: "GET",
    path: "/",
    config: {
      description: "protected endpoint",
      auth: {
        strategies: ["keycloak-jwt"],
        access: {
          scope: [
            "realm:admin",
            "editor",
            "other-resource:creator",
            "scope:foo.READ",
            "clientscope:profile",
          ],
        },
      },
      handler() {
        return "hello world";
      },
    },
  },
]);

API

Plugin Options

  • apiKey {Object} — The options object enabling an api key service as middleware
    Optional. Default: undefined.

    • url {string} — The absolute url to be requested. It's possible to use a pupa template with placeholders called realm and clientId getting rendered based on the passed plugin-related options.
      Example: http://barfoo.com/foo/{clientId}
      Required.

    • in {string} — Whether the api key is placed in the headers or query.
      Allowed values: headers & query
      Optional. Default: headers.

    • name {string} — The name of the related headers field or query key.
      Optional. Default: authorization.

    • prefix {string} — An optional prefix of the related api key value. Mind a trailing space if necessary.
      Optional. Default: Api-Key.

    • tokenPath {string} — The path to the access token in the response its body as dot notation.
      Optional. Default: access_token.

    • request {Object} – The detailed request options for got.
      Optional. Default: {}

Plugin + Strategy Options

These options can be set in both ways: strategy-specific and as default for all strategies via plugin-specific options. When defining just one strategy, it's totally fine to set the whole option object as plugin options. Keep in mind that name needs to be unique for each strategy, default is default.

By default, the Keycloak server has built-in two ways to authenticate the client: client ID and client secret (1), or with a signed JWT (2). This plugin supports both. If a non-live strategy is used, ensure that the identifier of the related realm key is included in their header as kid. Check the description of secret/publicKey/entitlement and the terminology for further information.

Strategies Online* Live** Scopes Truthy Option Note
(1) + (2) publicKey fast
(1) + (2) x flexible
(1) x x secret accurate
(1) + (2) x x x entitlement fine-grained

*: Plugin interacts with the Keycloak API
> **: Plugin validates token with help of the Keycloak API

Please mind that the accurate strategy is 4-5x faster than the fine-grained one.
> Hint: If you define neither secret nor public nor entitlement, the plugin retrieves the public key itself from {realmUrl}/protocol/openid-connect/certs.

  • name {string} – The unique name of the strategy
    Required. Example BizApps

  • realmUrl {string} – The absolute uri of the Keycloak realm.
    Required. Example: https://localhost:8080/auth/realms/testme

  • clientId {string} – The identifier of the Keycloak client/application.
    Required. Example: foobar

  • secret {string} – The related secret of the Keycloak client/application.
    Defining this option enables the traditional method described in the OAuth2 specification and performs an introspect request.
    Optional. Example: 1234-bar-4321-foo

  • publicKey {string|Buffer|Object} – The realm its public key related to the private key used to sign the token.
    Defining this option enables the offline and non-live validation. The public key has to be in PEM ({string|Buffer}) or JWK ({Object}) format. Algorithm has to be RSA-SHA256 compatible.
    Optional.

  • entitlement {boolean=true} – The token should be validated with the entitlement API to enable fine-grained authorization. Enabling this option decelerates the process marginally. Mind that false is an invalid value.
    Optional. Default: undefined.

  • minTimeBetweenJwksRequests {number} – The minimum time between JWKS requests in seconds.
    This is relevant for the online/non-live strategy retrieving JWKS from the Keycloak server.
    The value have to be a positive integer.
    Optional. Default: 0.

  • userInfo {Array.<?string>} — List of properties which should be included in the request.auth.credentials object besides scope and sub.
    Optional. Default: [].

  • cache {Object|boolean} — The configuration of the hapi.js cache powered by catbox. If the property exp ('expires at') is undefined, the plugin uses 60 seconds as default TTL. Otherwise the cache entry expires as soon as the token itself expires.
    Please mind that an enabled cache leads to disabled live validation after the related token is cached once.
    If false the cache is disabled. Use true or an empty object ({}) to use the built-in default cache. Otherwise just drop in your own cache configuration.
    Optional. Default: false.

await server.kjwt.validate(field {string}, name {string})

  • field {string} — The Bearer field, including the scheme (bearer) itself.
    Example: bearer 12345.abcde.67890.
    Required.
  • name {string} — The name strategy option, to select the strategy to be used.
    Example: BizApps.
    Required.

If an error occurs, it gets thrown — so take care and implement a kind of catching.
If the token is invalid, the result is false. Otherwise it is an object containing all relevant credentials.

Example

routes.js

async function register(server, options) {
  server.route([
    {
      method: "GET",
      path: "/",
      config: {
        auth: {
          strategies: ["keycloak-jwt"],
          access: {
            scope: [
              "realm:admin",
              "editor",
              "other-resource:creator",
              "scope:foo.READ",
            ],
          },
        },
        handler(req, reply) {
          reply(req.auth.credentials);
        },
      },
    },
  ]);
}

module.exports = {
  register,
  name: "example-routes",
  version: "0.0.1",
};

index.js

const hapi = require("@hapi/hapi");
const authKeycloak = require("hapi-auth-keycloak");
const routes = require("./routes");

const server = hapi.server({ port: 3000 });

const pluginOptions = {
  apiKey: {
    url: "http://barfoo.com/foo/foobar",
  },
};

const strategyOptions = {
  realmUrl: "https://localhost:8080/auth/realms/testme",
  clientId: "foobar",
  minTimeBetweenJwksRequests: 15,
  cache: true,
  userInfo: ["name", "email"],
};

process.on("SIGINT", async () => {
  try {
    await server.stop();
  } catch (err) {
    process.exit(err ? 1 : 0);
  }
});

(async () => {
  try {
    await server.register({
      plugin: authKeycloak,
      options: pluginOptions,
    });
    server.auth.strategy("keycloak-jwt", "keycloak-jwt", strategyOptions);
    await server.register({ plugin: routes });
    await server.start();
    console.log("Server started successfully");
  } catch (err) {
    console.error(err);
  }
})();

Migration Guides

v4.2 to v4.3

Features

  • It's now possible to register multiple strategies with the same scheme keycloak-jwt

Changes

  • name is a new unique strategy-related option.
  • apiKey.url its placeholders are replaced with plugin-related options, not the unique strategy ones.
  • The option setup changed. All plugin-related options are used as defaults for strategy-related options.
  • Even though every strategy-related option can also set via the plugin options, apiKey can only be set once in the plugin options.

In case of multiple registered strategies for this scheme:

  • Use at least a different name option in each strategy.
  • server.kjwt.validate requires name as second argument

Attention

Developing and Testing

First you have to install all dependencies:

$ npm install

To execute all unit tests once, use:

$ npm test

or to run tests based on file watcher, use:

$ npm start

To get information about the test coverage, use:

$ npm run coverage

Contribution

Fork this repository and push in your ideas.

Do not forget to add corresponding tests to keep up 100% test coverage.
For further information read the contributing guideline.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].