-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
199b0e5
commit 5311475
Showing
1 changed file
with
183 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,183 @@ | ||
--- | ||
# YAML header | ||
render_macros: false | ||
--- | ||
|
||
# JWT Extension for WireMock | ||
|
||
Adds Handlebars helpers for generating JWT, claims and JWKS. | ||
|
||
## Java/JVM usage | ||
|
||
### Step 1: Add to your build file | ||
|
||
For Maven users: | ||
|
||
```xml | ||
<dependency> | ||
<groupId>org.wiremock.extensions</groupId> | ||
<artifactId>wiremock-jwt-extension</artifactId> | ||
<version>0.1.0</version> | ||
</dependency> | ||
``` | ||
|
||
For Gradle users: | ||
|
||
```groovy | ||
dependencies { | ||
implementation 'org.wiremock.extensions:wiremock-jwt-extension-standalone:0.1.0' | ||
} | ||
``` | ||
|
||
### Step 2: Register the extension with your server | ||
|
||
```java | ||
new WireMockServer(wireMockConfig().extensions(JwtExtensionFactory.class)); | ||
``` | ||
|
||
### Step 3: Create a JWKS endpoint | ||
|
||
```java | ||
wm.stubFor( | ||
get(urlPathEqualTo("/.well-known/jwks.json")) | ||
.willReturn(okJson("{{jwks}}").withTransformers("response-template"))); | ||
``` | ||
|
||
### Step 4: Create a token endpoint | ||
|
||
```java | ||
wm.stubFor( | ||
get(urlPathEqualTo("/oauth/token")) | ||
.willReturn(okJson("{{jwt}}").withTransformers("response-template"))); | ||
``` | ||
|
||
|
||
## Customising the JWT | ||
|
||
The `jwt` helper has a number of parameters you can use to customise the generated token. | ||
|
||
### Expiry date | ||
|
||
You can customise expiry term either by setting the `maxAge` parameter e.g. | ||
|
||
{% raw %} | ||
```handlebars | ||
{{{jwt maxAge='12 days'}}} | ||
``` | ||
{% endraw %} | ||
|
||
or by setting an absolute expiry date e.g. | ||
|
||
{% raw %} | ||
```handlebars | ||
{{{jwt exp=(parseDate '2040-02-23T21:22:23Z')}}} | ||
``` | ||
{% endraw %} | ||
|
||
You can similarly set the `nbf` (not before) date: | ||
|
||
{% raw %} | ||
```handlebars | ||
{{{jwt nbf=(parseDate '2018-02-23T21:22:23Z')}}} | ||
``` | ||
{% endraw %} | ||
|
||
### Standard claims | ||
|
||
Standard claims can be set as follows. | ||
|
||
Issuer: | ||
|
||
{% raw %} | ||
```handlebars | ||
{{{jwt iss='https://jwt-example.wiremockapi.cloud/'}}} | ||
``` | ||
{% endraw %} | ||
|
||
Audience: | ||
|
||
{% raw %} | ||
```handlebars | ||
{{{jwt aud='https://jwt-target.wiremockapi.cloud/'}}} | ||
``` | ||
{% endraw %} | ||
|
||
Subject: | ||
|
||
{% raw %} | ||
```handlebars | ||
{{{jwt sub='jonsmith'}}} | ||
``` | ||
{% endraw %} | ||
|
||
### Custom claims | ||
|
||
You can also set any custom claim you wish via named parameters e.g. | ||
|
||
{% raw %} | ||
```handlebars | ||
{{{jwt | ||
isAdmin=true | ||
quota=23 | ||
score=0.96 | ||
email='[email protected]' | ||
signupDate=(parseDate '2017-01-02T03:04:05Z') | ||
}}} | ||
``` | ||
{% endraw %} | ||
|
||
### Signing with RS256 | ||
|
||
By setting the `alg` parameter, the token can be signed using the public/private key | ||
algorithm: | ||
|
||
{% raw %} | ||
```handlebars | ||
{{{jwt alg='RS256'}}} | ||
``` | ||
{% endraw %} | ||
|
||
## Retrieving keys | ||
|
||
For clients to be able to validate JWTs, they need to be able to retrieve either | ||
the shared secret or the public key, depending on the signing algorithm. | ||
|
||
### Getting all keys for your mock API | ||
|
||
The keys used to sign tokens for a particular mock API can be retrieved via the | ||
settings admin API resource. To fetch these via curl, you can do the following: | ||
|
||
``` | ||
curl http://localhost:8080/__admin/settings | ||
``` | ||
|
||
This will return a JSON document like this, from which you can retrieve the any of the | ||
keys: | ||
|
||
```json | ||
{ | ||
"settings": { | ||
"extended": { | ||
"jwt": { | ||
"hs256Secret": "...", | ||
"rs256PublicKeyId": "...", | ||
"rs256PublicKey": "-----BEGIN RSA PUBLIC KEY-----\n...\n-----END RSA PUBLIC KEY-----\n", | ||
"rs256PrivateKey": "-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----\n" | ||
} | ||
} | ||
} | ||
} | ||
``` | ||
|
||
### The JSON Web Key Set (JWKS) | ||
|
||
When using `RS256` (public/private key) signing, it is common for clients to fetch | ||
the public key for verification via a JSON Web Key Set (JWKS) endpoint. You serve | ||
a JWKS from your mock API simply by adding a stub containing the following response | ||
body (with templating enabled): | ||
|
||
{% raw %} | ||
```handlebars | ||
{{{jwks}}} | ||
``` | ||
{% endraw %} |