In our last call there was some concern about the burden the use of JWKS configuration as a URL would impose on deployments. Previously there was also concern about having to support PEM keys bundled in applications. One way to potentially address both concerns would be include support for custom URL protocol handlers as part of the configuration changes. I have added tests in the sandbox that illustrate how this would work:
/**
* Validate that the jwks: protocol handler works
* @throws Exception on failure
*/
@Test
public void testJwksURL() throws Exception {
// Load the /signer-keyset.jwk JWKS resource from the classpath as a JWKS
URL signerJwk = new URL("jwks:/signer-keyset.jwk");
String signerJwksContent = signerJwk.getContent().toString();
System.out.println(signerJwksContent);
JsonObject jwks = Json.createReader(new StringReader(signerJwksContent)).readObject();
JsonArray keys = jwks.getJsonArray("keys");
JsonObject key = keys.getJsonObject(0);
Assert.assertEquals(key.getJsonString("kty").getString(), "RSA");
Assert.assertEquals(key.getJsonString("use").getString(), "sig");
Assert.assertEquals(key.getJsonString("kid").getString(), "jwk-test");
Assert.assertEquals(key.getJsonString("alg").getString(), "RS256");
Assert.assertEquals(key.getJsonString("e").getString(), "AQAB");
Assert.assertTrue(key.getJsonString("n").getString().startsWith("uGU_nmjYC7cKRR89NCAo"));
}
/**
* Validate that the pemjwks: protocol handler works
* @throws Exception on failure
*/
@Test
public void testPemJwksURL() throws Exception {
// Load the /publicKey.pem PEM encoded public key resource from the classpath as a JWKS
URL signerJwk = new URL("pemjwks:/publicKey.pem?kid=pem-test");
String signerJwksContent = signerJwk.getContent().toString();
System.out.println(signerJwksContent);
JsonObject jwks = Json.createReader(new StringReader(signerJwksContent)).readObject();
JsonArray keys = jwks.getJsonArray("keys");
JsonObject key = keys.getJsonObject(0);
Assert.assertEquals(key.getJsonString("kty").getString(), "RSA");
Assert.assertEquals(key.getJsonString("use").getString(), "sig");
Assert.assertEquals(key.getJsonString("kid").getString(), "pem-test");
Assert.assertEquals(key.getJsonString("alg").getString(), "RS256");
Assert.assertEquals(key.getJsonString("e").getString(), "AQAB");
Assert.assertTrue(key.getJsonString("n").getString().startsWith("livFI8qB4D0y2jy0Cf"));
}
What do you think of this as a way of supporting both embedded and remote public keys?