|
| 1 | +:doctype: book |
| 2 | +include::attributes.adoc[] |
| 3 | + |
| 4 | +[[configuration]] |
| 5 | + |
| 6 | += Generate JWT Tokens |
| 7 | + |
| 8 | +JWT claims can be signed or encrypted or signed first and the nested JWT token encrypted. Signing the claims is used |
| 9 | +most often to secure the claims. What is known today as a JWT token is typically produced by signing the claims in a |
| 10 | +JSON format using the steps described in the https://tools.ietf.org/html/rfc7515[JSON Web Signature] specification. |
| 11 | +However, when the claims are sensitive, their confidentiality can be guaranteed by following the steps described in the |
| 12 | +https://tools.ietf.org/html/rfc7516[JSON Web Encryption] specification to produce a JWT token with the encrypted claims. |
| 13 | +Finally both the confidentiality and integrity of the claims can be further enforced by signing them first and then |
| 14 | +encrypting the nested JWT token. |
| 15 | + |
| 16 | +SmallRye JWT provides an API for securing the JWT claims using all of these options. |
| 17 | + |
| 18 | +== Create JwtClaimsBuilder and set the claims |
| 19 | + |
| 20 | +The first step is to initialize a `JwtClaimsBuilder` using one of the options below and add some claims to it: |
| 21 | + |
| 22 | +[source,java] |
| 23 | +---- |
| 24 | +import java.util.Collections; |
| 25 | +import io.smallrye.jwt.build.Jwt; |
| 26 | +import io.smallrye.jwt.build.JwtClaimsBuilder; |
| 27 | +... |
| 28 | +// Create an empty builder and add some claims |
| 29 | +JwtClaimsBuilder builder1 = Jwt.claims(); |
| 30 | +builder1.claim("customClaim", "custom-value").issuer("https://issuer.org"); |
| 31 | +
|
| 32 | +// Builder created from the existing claims |
| 33 | +JwtClaimsBuilder builder2 = Jwt.claims("/tokenClaims.json"); |
| 34 | +
|
| 35 | +// Builder created from a map of claims |
| 36 | +JwtClaimsBuilder builder3 = Jwt.claims(Collections.singletonMap("customClaim", "custom-value")); |
| 37 | +---- |
| 38 | + |
| 39 | +The API is fluent so the builder initialization can be done as part of the fluent API sequence. The builder will also |
| 40 | +set `iat (issued at) to the current time, `exp`(expires at) to 5 minutes away from the current time and `jti` |
| 41 | +(unique token identifier) claims if they have not already been set, so one can skip setting them when possible. |
| 42 | + |
| 43 | +The next step is to decide how to secure the claims. |
| 44 | + |
| 45 | +== Sign the claims |
| 46 | + |
| 47 | +The claims can be signed immediately or after the `JSON Web Signature` headers have been set: |
| 48 | + |
| 49 | +[source,java] |
| 50 | +---- |
| 51 | +import io.smallrye.jwt.build.Jwt; |
| 52 | +... |
| 53 | +
|
| 54 | +// Sign the claims using the private key loaded from the location set with a 'smallrye.jwt.sign.key-location' property. |
| 55 | +// No 'jws()' transition is necessary. |
| 56 | +String jwt1 = Jwt.claims("/tokenClaims.json").sign(); |
| 57 | +
|
| 58 | +// Set the headers and sign the claims with an RSA private key loaded in the code (the implementation of this method is omitted). Note a 'jws()' transition to a 'JwtSignatureBuilder'. |
| 59 | +String jwt2 = Jwt.claims("/tokenClaims.json").jws().signatureKeyId("kid1").header("custom-header", "custom-value").sign(getPrivateKey()); |
| 60 | +---- |
| 61 | + |
| 62 | +Note the `alg` (algorithm) header is set to `RS256` by default. |
| 63 | + |
| 64 | +== Encrypt the claims |
| 65 | + |
| 66 | +The claims can be encrypted immediately or after the `JSON Web Encryption` headers have been set the same way as they |
| 67 | +can be signed. The only minor difference is that encrypting the claims always requires a `jwe() JwtEncryptionBuilder` |
| 68 | +transition: |
| 69 | + |
| 70 | +[source,java] |
| 71 | +---- |
| 72 | +import io.smallrye.jwt.build.Jwt; |
| 73 | +... |
| 74 | +
|
| 75 | +// Encrypt the claims using the public key loaded from the location set with a 'smallrye.jwt.encrypt.key-location' property. |
| 76 | +String jwt1 = Jwt.claims("/tokenClaims.json").jwe().encrypt(); |
| 77 | +
|
| 78 | +// Set the headers and encrypt the claims with an RSA public key loaded in the code (the implementation of this method is omitted). |
| 79 | +String jwt2 = Jwt.claims("/tokenClaims.json").jwe().header("custom-header", "custom-value").encrypt(getPublicKey()); |
| 80 | +---- |
| 81 | + |
| 82 | +Note the `alg` (key management algorithm) header is set to `RSA-OAEP-256` (it will be changed to `RSA-OAEP` in a future |
| 83 | +version of smallrye-jwt) and the `enc` (content encryption header) is set to `A256GCM` by default. |
| 84 | + |
| 85 | +== Sign the claims and encrypt the nested JWT token |
| 86 | + |
| 87 | +The claims can be signed and then the nested JWT token encrypted by combining the sign and encrypt steps. |
| 88 | + |
| 89 | +[source,java] |
| 90 | +---- |
| 91 | +import io.smallrye.jwt.build.Jwt; |
| 92 | +... |
| 93 | +
|
| 94 | +// Sign the claims and encrypt the nested token using the private and public keys loaded from the locations set with the 'smallrye.jwt.sign.key-location' and 'smallrye.jwt.encrypt.key-location' properties respectively. |
| 95 | +String jwt = Jwt.claims("/tokenClaims.json").innerSign().encrypt(); |
| 96 | +---- |
0 commit comments