|
15 | 15 | ---
|
16 | 16 |
|
17 | 17 | ## Introduction
|
18 |
| -**hapi-auth-keycloak** is a plugin for [hapi.js][hapijs] which enables to protect your endpoints in a smart but professional manner using [Keycloak][keycloak] as authentication service. It is inspired by the related [express.js middleware][keycloak-node]. The plugin validates the passed [`Bearer` token][bearer] online with help of the [Keycloak][keycloak] server and optionally caches successfully validated tokens and the related user data using [`catbox`][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][hapijs]-integrated [authentication feature][hapi-route-options]. Besides the authentication strategy it is possible to validate tokens by yourself, e.g. to authenticate incoming websocket or queue messages. |
| 18 | +**hapi-auth-keycloak** is a plugin for [hapi.js][hapijs] which enables to protect your endpoints in a smart but professional manner using [Keycloak][keycloak] as authentication service. It is inspired by the related [express.js middleware][keycloak-node]. The plugin validates the passed [`Bearer` token][bearer] offline with a provided public key or online with help of the [Keycloak][keycloak] server. Optionally, the successfully validated tokens and the related user data get cached using [`catbox`][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][hapijs]-integrated [authentication feature][hapi-route-options]. Besides the authentication strategy it is possible to validate tokens by yourself, e.g. to authenticate incoming websocket or queue messages. |
19 | 19 |
|
20 | 20 | This plugin is implemented in ECMAScript 6 without any transpilers like [`babel`][babel].<br/>
|
21 | 21 | Additionally [`standard`][standardjs] and [`ava`][avajs] are used to grant a high quality implementation.<br/>
|
@@ -60,11 +60,10 @@ Finally register the plugin, set the correct options and the authentication stra
|
60 | 60 | server.register({
|
61 | 61 | register: authKeycloak,
|
62 | 62 | options: {
|
63 |
| - client: { |
64 |
| - realmUrl: 'https://localhost:8080/auth/realms/testme', |
65 |
| - clientId: 'foobar', |
66 |
| - secret: '1234-bar-4321-foo' |
67 |
| - }, |
| 63 | + realmUrl: 'https://localhost:8080/auth/realms/testme', |
| 64 | + clientId: 'foobar', |
| 65 | + secret: '1234-bar-4321-foo', |
| 66 | + minTimeBetweenJwksRequests: 15, |
68 | 67 | cache: {},
|
69 | 68 | userInfo: ['name', 'email']
|
70 | 69 | }
|
@@ -108,37 +107,39 @@ server.route([
|
108 | 107 | ## API
|
109 | 108 | #### Plugin Options
|
110 | 109 |
|
111 |
| -- `realmUrl {string}`: The absolute uri of the Keycloak realm<br/> |
| 110 | +--- |
| 111 | + |
| 112 | +**Hint**: By default, the Keycloak server has built-in two ways to authenticate the client: client ID and client secret, or with a signed JWT. This plugin supports both. Check the description of `secret` and `publicKey` for further information: |
| 113 | + |
| 114 | +| Strategy | Online | Option | |
| 115 | +|:------------|:------:|:------------| |
| 116 | +| ID + Secret | x | `secret` | |
| 117 | +| Signed JWT | x | | |
| 118 | +| Signed JWT | | `publicKey` | |
| 119 | + |
| 120 | +--- |
| 121 | + |
| 122 | + |
| 123 | +- `realmUrl {string}`: The absolute uri of the Keycloak realm.<br/> |
112 | 124 | Required. Example: `https://localhost:8080/auth/realms/testme`<br/>
|
113 | 125 |
|
114 |
| -- `clientId {string}` The identifier of the Keycloak client<br/> |
| 126 | +- `clientId {string}` The identifier of the Keycloak client/application.<br/> |
115 | 127 | Required. Example: `foobar`<br/>
|
116 | 128 |
|
| 129 | +- `secret {string}` The related secret of the Keycloak client/application.<br/> |
| 130 | +Defining this option enables the traditional method described in the OAuth2 specification.<br/> |
| 131 | +Optional. Example: `1234-bar-4321-foo`<br/> |
| 132 | + |
| 133 | +- `publicKey {string}` The related public key of the Keycloak client/application.<br/> |
| 134 | +Defining this option enables the offline validation using signed JWTs. The public key has to be in [PEM][pem] or [JWK][jwk] format. If you define neither `secret` nor `public` key, the plugin assumes that a signed JWT has to be validated – it retrieves the public key itself from `{realmUrl}/protocol/openid-connect/certs`. The offline strategy its performance is higher but the online strategy is the most flexible one.<br/> |
| 135 | +Optional. |
117 | 136 |
|
118 |
| -- `secret {string}` The related secret of the Keycloak client<br/> |
119 |
| -Required (or `publicKey`). Example: `1234-bar-4321-foo`<br/> |
| 137 | +- `minTimeBetweenJwksRequests {number}` – The minimum time between JWK requests in seconds.<br/> |
| 138 | +The value have to be a positive integer.<br/> |
| 139 | +Optional. Default: `0`. |
120 | 140 |
|
121 |
| - |
122 |
| -- `publicKey {string}` The related public key of the Keycloak client<br/> |
123 |
| -Required (or `secret`). Example: |
124 |
| -``` |
125 |
| ------BEGIN RSA PUBLIC KEY----- |
126 |
| -MIICCgKCAgEAur96MoQa/blg5eJFqmN//V4oQjKaBJl6KEvWSGAVgRm2PsnFKzCJ |
127 |
| -K9aJrUjETS473/x6fAHXyF5QKun6avNxpWs2VzwlO4t8Bi2EpSW2w0led2OzR/MF |
128 |
| -CYUX1Bg00OXLmdh0kvemABHXSOL4Zs4nN95rr77JsdG6ntylWmtnZlofySwLjFrX |
129 |
| -B2JFpunl4n7eF7y8vD4Zyycvi+xl+OuMA6qomLQmfIDF0qJh0QMt/xh6CB4ooK5a |
130 |
| -Fy6VHORU5gS6MoSgJ78ZPhqmKayRd6U0rhDOq7bWiVykktTPdB1X/YlMbQHonyqZ |
131 |
| -0z2sh7e7olroUdE1FsDi0SdxV2Zzvff8IIPSGT74gQuaU4buoVUpMjSdXDfJw9m4 |
132 |
| -i/mhsZwX1/MUU8Oq1AsBHdgTkNVaVwFc6Z7AqJSGW/mxMKQqspOr+/BAM8pnw5BC |
133 |
| -R/RnZBJfMjAYiSh6rVYuEWUBBLgZWIRNAMyRwS8OtWxADfOBtVwn8fmw8schro9X |
134 |
| -D17VcqTdjlS1Mkr73ZoD1GagWZvuSOaz2P0PhnfapRUF1KkbjjnbyzLpfT8Mgovv |
135 |
| -xBQJDIcRYL5oetXu//V5rNAr0na4zMBkPOi3ArpFp+Z4YKulYmSEG//216rLmzjl |
136 |
| -WKEkH1OK39jddDrMTidlxDKY+THheyQBPZ6pFfbKEM5281glYjkeQpECAwEAAQ== |
137 |
| ------END RSA PUBLIC KEY----- |
138 |
| -``` |
139 |
| - |
140 |
| -- `cache {Object|false}` — The configuration of the [hapi.js cache](https://hapijs.com/api#servercacheoptions) powered by [catbox][catbox].<br/> |
141 |
| -If `false` the cache is disabled. Use an empty object (`{}`) to use the built-in default cache.<br/> |
| 141 | +- `cache {Object|boolean}` — The configuration of the [hapi.js cache](https://hapijs.com/api#servercacheoptions) powered by [catbox][catbox].<br/> |
| 142 | +If `false` the cache is disabled. Use `true` or an empty object (`{}`) to use the built-in default cache.<br/> |
142 | 143 | Optional. Default: `false`.
|
143 | 144 |
|
144 | 145 | - `userInfo {Array.<?string>}` — List of properties which should be included in the `request.auth.credentials` object besides `scope` and `sub`.<br/>
|
@@ -189,11 +190,10 @@ process.on('SIGINT', () => {
|
189 | 190 | server.register({
|
190 | 191 | register: authKeycloak,
|
191 | 192 | options: {
|
192 |
| - client: { |
193 |
| - realmUrl: 'https://localhost:8080/auth/realms/testme', |
194 |
| - clientId: 'foobar', |
195 |
| - secret: '1234-bar-4321-foo' |
196 |
| - }, |
| 193 | + realmUrl: 'https://localhost:8080/auth/realms/testme', |
| 194 | + clientId: 'foobar', |
| 195 | + secret: '1234-bar-4321-foo', |
| 196 | + minTimeBetweenJwksRequests: 15, |
197 | 197 | cache: {},
|
198 | 198 | userInfo: ['name', 'email']
|
199 | 199 | }
|
@@ -243,3 +243,5 @@ For further information read the [contributing guideline](CONTRIBUTING.md).
|
243 | 243 | [catbox]: https://github.com/hapijs/catbox
|
244 | 244 | [bearer]: https://tools.ietf.org/html/rfc6750
|
245 | 245 | [hapi-route-options]: https://hapijs.com/api#route-options
|
| 246 | +[jwk]: https://tools.ietf.org/html/rfc7517 |
| 247 | +[pem]: https://tools.ietf.org/html/rfc1421 |
0 commit comments