@@ -125,6 +125,9 @@ JJWT is open source under the terms of the [Apache 2.0 License](http://www.apach
125
125
* [ JWK Thumbprint URI] ( #jwk-thumbprint-uri )
126
126
* [ JWK Security Considerations] ( #jwk-security )
127
127
* [ JWK ` toString() ` Safety] ( #jwk-tostring )
128
+ * [ JWK Sets] ( #jwkset )
129
+ * [ Create a JWK Set] ( #jwkset-create )
130
+ * [ Read a JWK Set] ( #jwkset-read )
128
131
* [ Compression] ( #compression )
129
132
* [ Custom Compression Algorithm] ( #compression-custom )
130
133
* [ JSON Processor] ( #json )
@@ -2788,6 +2791,91 @@ This code would print the following string literal to the System console:
2788
2791
This is true for all secret or private key members in `SecretJwk` and `PrivateJwk` (e.g. `RsaPrivateJwk`,
2789
2792
`EcPrivateJwk`, etc) instances.
2790
2793
2794
+ <a name="jwkset"></a>
2795
+ ## JWK Sets
2796
+
2797
+ The JWK specification specification also defines the concept of a
2798
+ [JWK Set](https://datatracker.ietf.org/doc/html/rfc7517#section-5):
2799
+
2800
+ A JWK Set is a JSON object that represents a set of JWKs. The JSON
2801
+ object MUST have a "keys" member, with its value being an array of
2802
+ JWKs.
2803
+
2804
+ For example:
2805
+
2806
+ ```json
2807
+ {
2808
+ "keys": [jwk1, jwk2, ...]
2809
+ }
2810
+ ```
2811
+ Where `jwk1`, `jwk2`, etc., are each a single [JWK](#jwk) JSON Object.
2812
+
2813
+ A JWK Set _may_ have other members that are peers to the `keys` member, but the JWK specification does not define any
2814
+ others - any such additional members would be custom or unique based on an application' s needs or preferences.
2815
+
2816
+ A JWK Set can be useful for conveying multiple keys simultaneously. For example, an identity web service could expose
2817
+ all of its RSA or Elliptic Curve public keys that might be used for various purposes or different algorithms to
2818
+ 3rd parties or API clients as a single JWK Set JSON Object or document. An API client can then parse the JWK Set
2819
+ to obtain the keys that might be used to verify or decrypt JWTs sent by the web service.
2820
+
2821
+ JWK Sets are (mostly) simple collections of JWKs , and they are easily supported by JJWT with parallel builder/ parser
2822
+ concepts we' ve seen above.
2823
+
2824
+ <a name="jwkset-create"></a>
2825
+ ### Create a JWK Set
2826
+
2827
+ You create a JWK Set as follows:
2828
+
2829
+ 1. Use the `Jwks.set()` method to create a `JwkSetBuilder` instance.
2830
+ 2. Call the `add(Jwk)` method any number of times to add one or more JWKs to the set.
2831
+ 3. Call builder methods to set any additional JSON members if desired, or the `operationPolicy(KeyOperationPolicy)`
2832
+ builder method to control what key operations may be assigned to any given JWK added to the set.
2833
+ 4. Call the `build()` method to produce the resulting JWK Set.
2834
+
2835
+ For example:
2836
+
2837
+ ```java
2838
+ Jwk<?> jwk = Jwks.builder()/* ... */.build();
2839
+ SecretJwk = Jwks.set() // 1
2840
+ .add(jwk) // 2, appends a key
2841
+ //.add(aCollection) // append multiple keys
2842
+ //.keys(allJwks) // sets/replaces all keys
2843
+ //.add("aName", "aValue") // 3, optional
2844
+ //.operationPolicy(Jwks.OP // 3, optional
2845
+ // .policy()
2846
+ // /* etc... */
2847
+ // .build())
2848
+ //.provider(aJcaProvider) // optional
2849
+ .build(); // (4)
2850
+ ```
2851
+
2852
+ As shown, you can optionally configure the `.operationPolicy(KeyOperationPolicy)` method using a
2853
+ `Jwts.OP.policy()` builder. A `KeyOperationPolicy` allows you control what operations are allowed for any JWK
2854
+ before being added to the JWK Set; any JWK that does not match the policy will be rejected and not added to the set.
2855
+ JJWT internally defaults to a standard RFC-compliant policy, but you can create a
2856
+ policy to override the default if desired using the `Jwks.OP.policy()` builder method.
2857
+
2858
+ <a name="jwkset-read"></a>
2859
+ ### Read a JWK Set
2860
+
2861
+ You can read/parse a JWK Set by building a JWK Set `Parser` and parsing the JWK Set JSON with one of its various
2862
+ `parse` methods:
2863
+
2864
+ ```java
2865
+ JwkSet jwkSet = Jwks.setParser()
2866
+ //.provider(aJcaProvider) // optional
2867
+ //.deserializer(deserializer) // optional
2868
+ //.policy(aKeyOperationPolicy) // optional
2869
+ .build() // create the parser
2870
+ .parse(json); // actually parse JSON String, InputStream, Reader, etc.
2871
+
2872
+ jwkSet.forEach(jwk -> System.out.println(jwk));
2873
+ ```
2874
+
2875
+ As shown above, you can specify a custom JCA Provider, [JSON deserializer](#json) or `KeyOperationPolicy` in the
2876
+ same way as the `JwkSetBuilder`. Any JWK that does not match the default (or configured) policy will be
2877
+ rejected. You can create a policy to override the default if desired using the `Jwks.OP.policy()` builder method.
2878
+
2791
2879
<a name="compression"></a>
2792
2880
## Compression
2793
2881
0 commit comments