Package Exports
- hapi-auth-keycloak
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (hapi-auth-keycloak) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
hapi-auth-keycloak
JSON Web Token based Authentication powered by Keycloak
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 online with help of the Keycloak server and optionally caches successfully validated tokens and the related user data using catbox
. The caching enables a fast processing although the user data don't get changed until the token expires. It plays well with the hapi.js-integrated authentication feature. Besides the authentication strategy it is possible to validate tokens by yourself, e.g. to authenticate incoming websocket or queue messages.
This plugin is implemented in ECMAScript 6 without any transpilers like babel
.
Additionally standard
and ava
are used to grant a high quality implementation.
Installation
For installation use the Node Package Manager:
$ npm install --save hapi-auth-keycloak
or clone the repository:
$ git clone https://github.com/felixheck/hapi-auth-keycloak
Alternatively use the Yarn Package Manager:
$ yarn add 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 and the corresponding connection if not already done:
const server = new Hapi.Server();
server.connection({
port: 8888,
host: 'localhost',
});
Registration
Finally register the plugin, set the correct options and the authentication strategy:
server.register({
register: authKeycloak,
options: {
client: {
realmUrl: 'https://localhost:8080/auth/realms/testme',
clientId: 'foobar',
secret: '1234-bar-4321-foo'
},
cache: {},
userInfo: ['name', 'email']
}
}, function(err) {
if (err) {
throw err;
}
server.auth.strategy('keycloak-jwt', 'keycloak-jwt');
});
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 a resource with an application role for the current app, use the role name (e.g.
editor
). - To secure a resource with an application role for a different app, prefix the role name (e.g.
other-app:creator
) - To secure a resource with a realm role, prefix the role name with
realm:
(e.g.realm:admin
).
server.route([
{
method: 'GET',
path: '/',
config: {
description: 'protected endpoint',
auth: {
strategies: ['keycloak-jwt'],
access: {
scope: ['realm:admin', 'editor', 'other-app:creator']
}
},
handler (req, reply) {
reply('hello world')
}
}
},
])
API
Plugin Options
client {Object}
: The configuration ofkeycloak-auth-utils
itsGrantManager
. The suggested minimum configuration containsrealmUrl
,clientId
andsecret
.
Required.cache {Object|false}
: The configuration of the hapi.js cache powered by catbox.
Iffalse
the cache is disabled. Use an empty object to use the built-in default cache.
Optional. Default:false
.userInfo {Array.<?string>}
: List of properties which should be included in therequest.auth.credentials
object besidesscope
andsub
.
Optional. Default:[]
.
server.kjwt.validate(field {string}, done {Function})
Uses internally GrantManager.prototype.validateAccessToken()
.
field {string}
: TheBearer
field, including the scheme (bearer
) itself.
Example:bearer 12345.abcde.67890
.
Required.done {Function}
: The callback handler is passederr {Error}, result {Object|false}
(error-first approach).
If an error occurs,err
is notnull
. If the token is invalid, theresult
isfalse
. Otherwise it is an object containing all relevant credentials.
Required.
Example
const Hapi = require('hapi');
const authKeycloak = require('hapi-auth-keycloak');
const server = new Hapi.Server()
server.connection({ port: 3000, host: 'localhost' })
server.route([
{
method: 'GET',
path: '/',
config: {
description: 'protected endpoint',
auth: {
strategies: ['keycloak-jwt'],
access: {
scope: ['realm:admin', 'editor', 'other-app:creator']
}
},
handler (req, reply) {
reply('hello world')
}
}
},
])
process.on('SIGINT', () => {
server.stop().then((err) => {
process.exit((err) ? 1 : 0)
})
})
server.register({
register: authKeycloak,
options: {
client: {
realmUrl: 'https://localhost:8080/auth/realms/testme',
clientId: 'foobar',
secret: '1234-bar-4321-foo'
},
cache: {},
userInfo: ['name', 'email']
}
}).then(() => {
server.auth.strategy('keycloak-jwt', 'keycloak-jwt');
server.start()
})
.catch(console.error)
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.