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.
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
First you have to import the module:
const authKeycloak = require('hapi-auth-keycloak');
Afterwards create your hapi server and the corresponding connection if not already done:
const server = new Hapi.Server();
server.connection({
port: 8888,
host: 'localhost',
});
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: {}
}
}, function(err) {
if (err) {
throw err;
}
server.auth.strategy('keycloak-jwt', 'keycloak-jwt');
});
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')
}
}
},
])
-
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
.
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.
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: {}
}
}).then(() => {
server.auth.strategy('keycloak-jwt', 'keycloak-jwt');
server.start()
})
.catch(console.error)
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
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.