The example json is indeed a JWK Set in the sense of RFC7517.
The test in the question is not using the JJWT library in the intended way and confuses "keys" in the JSON sense, "keys" in the Java Map interface sense and "keys" in the JWK Set sense of the term.
The JwkSet
is a direct representation of the json object and as such a Map<String,?>
. The containsKey
and keySet
methods are Map
methods. The correct method to iterate over the JWK "Keys" is the JwkSet#getKeys()
method (as pointed out by @andrewJames in the comments of the question). The returning iterator can be converted to a List<Jwk<?>>
easily. This is a passing test:
String json = "{'keys':[{'kid':'key1','kty':'RSA','alg':'RS256','use':'sig','n':'jki4-Fw66lIy6oHk_YHLReGkdX3QkiizGUQHGeG_xjQUbwlOFejYm-CsMjWEpZcohX0BQVZomnrMCZC_qjNy-Tg5AIFcQZGXehT4kH_DXQZZR4OgT3uKvEEbMEYhZMPj5Bs9--420ONvCLMTU720UXqSF9IrXsuxtRZuaijwkMpQ2t9nIuJ6NKo_CBJHyeVvfLKN3a83Zi-6It6dkiLsOSvhQfbUAsr0NeKAobwmqGt9lT_K_JoLRVqTzFEC-XT7keobMdT9cKba2ML7Yz982Tr5BuGLXZTm7nfPKdk9Bi68HnO82Aas19_D5HJRieW7FqeqwE5MVl6E3IFt8HKblw','e':'AQAB','x5c':['MIICqTCCAZECBgFxOn9tejANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1hY2FkZW1pY2Nsb3VkMB4XDTIwMDQwMjEwNDQyMVoXDTMwMDQwMjEwNDYwMVowGDEWMBQGA1UEAwwNYWNhZGVtaWNjbG91ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAI5IuPhcOupSMuqB5P2By0XhpHV90JIosxlEBxnhv8Y0FG8JThXo2JvgrDI1hKWXKIV9AUFWaJp6zAmQv6ozcvk4OQCBXEGRl3oU+JB/w10GWUeDoE97irxBGzBGIWTD4+QbPfvuNtDjbwizE1O9tFF6khfSK17LsbUWbmoo8JDKUNrfZyLiejSqPwgSR8nlb3yyjd2vN2YvuiLenZIi7Dkr4UH21ALK9DXigKG8JqhrfZU/yvyaC0Vak8xRAvl0+5HqGzHU/XCm2tjC+2M/fNk6+Qbhi12U5u53zynZPQYuvB5zvNgGrNffw+RyUYnluxanqsBOTFZehNyBbfBym5cCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAJ+N/5p1bzHGgBT45cTe23Q3n0j8xogrJKk0LJLmcZTOU2nkcQhZeL4bpw/7eJasgnXCIMk37Ti8xiZKLPhSrRg0BcNIrKmrtA+2x6jDRIc0DoU3P83fM5h4ShUJAW+aKOx7JpV3E0KkOPzHbCRCB2w7oCleZHG9lJAGkcHAQQ01aIfyU3ow66kdAHyB6sAAnRXMf6aogTguqPVB8uAE3VTAWZDiPwyhqo/IVWDMs73bUty8qLDDj4Ei0Q+DcND3WghyeOGm8lCmAzPgl/zzphkQ6P+4Sq1gW06yfVvj862CuY9i6oBTldtAUvjKxCzl+QS8KzQBnB0oUzaFh8vHKYw=='],'x5t':'6yqDA3RjYFZrc3DVcyVrvkNiMA0','x5t#S256':'ifr81ikFJWOiNf2FDgW8dSOu5HEajKuwfGIw78G--Jw'},{'kid':'key2','kty':'RSA','alg':'RS512','use':'sig','n':'kKrdBB_DT37-GT75n_HdOSS0wxXIuheahBdJwTCHmB2Uk3IATjOpiFZjB8qAZ5d00AUu-oZrHG2VgnJq1jUiSb-RDYJTwA1lFXKEJu5CZwAB9xlfCFRXqPs9AL3-2l9-i5ajkMbSE10-S3dacwsrCFd-FL7w0428K7DHjtdwA0mWCyZW6nqWc7lutXhIfFlSmo7GY8M9tuMoOAOXOnLa0MYGh6G1jGvK8pNEyBTnKNEWqAIZhH8ENPMLm4vNFkuenFnP5VzcFNppwt3FnVFetnwudFPfEzUeHqyH7EsdOooFbD4IBu1iWXdI09uGCIJ30BJ2Q-OpXLGMur_YhXMb-Q','e':'AQAB','x5c':['MIICqTCCAZECBgGEexA7YjANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1hY2FkZW1pY2Nsb3VkMB4XDTIyMTExNTExMzExMloXDTMyMTExNTExMzI1MlowGDEWMBQGA1UEAwwNYWNhZGVtaWNjbG91ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJCq3QQfw09+/hk++Z/x3TkktMMVyLoXmoQXScEwh5gdlJNyAE4zqYhWYwfKgGeXdNAFLvqGaxxtlYJyatY1Ikm/kQ2CU8ANZRVyhCbuQmcAAfcZXwhUV6j7PQC9/tpffouWo5DG0hNdPkt3WnMLKwhXfhS+8NONvCuwx47XcANJlgsmVup6lnO5brV4SHxZUpqOxmPDPbbjKDgDlzpy2tDGBoehtYxryvKTRMgU5yjRFqgCGYR/BDTzC5uLzRZLnpxZz+Vc3BTaacLdxZ1RXrZ8LnRT3xM1Hh6sh+xLHTqKBWw+CAbtYll3SNPbhgiCd9ASdkPjqVyxjLq/2IVzG/kCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAQ4kzB7EwhUTGSr/IpAQa+viF7uYGxk+Iiec/s+ShfkFLoMPw+y9l5alwvnKAgTI1Pxrjha8Hu2OsCtGtu8ziJNd65VQiNoFsZp71WGq0+7+Zcqmk182CmjqoN+io7yfgg7N5/VygquHIY3aNB4riruQrbR33fQ49mjpZIM2eohU1teycfpwPCObTRGg5jZg+iUREy01k+QZplxgOqgyqrtTDUKoxZr8WwAWjlCBWyylOT5eEA/777yObYogmfrpNovo+dw1szaHB4BGfX1S522UUfRDAMtOTsjfCnusYEZsMUWXJe46ZLSYJsmIpGw4UwSC7I371elrC/dTzCSREpQ=='],'x5t':'PwDhZrjmydYTXbB3skSdfamw5Xk','x5t#S256':'44mNK5ARKWGn8S7R0tfEeJ6SVqpLp73VSeQeG2wMATE'}]}"
.replace("'", "\"");
JwkSet jwks = Jwks.setParser().build().parse(json);
assert "keys".equals(String.join("", jwks.keySet()));
List<Jwk<?>> keys = jwks.getKeys().stream().toList();
assert keys.get(0).getId().equals("key1");
assert keys.get(1).getId().equals("key2");
assert 2 == keys.size();
Source: lhazlewood's comment in the JJWT repository Discussion#1002