Issue
I have a client sending in a JWKS like this:
{
"keys": [
"kty": "RSA",
"use": "sig",
"alg": "RS256",
"kid": "...",
"x5t": "...",
"custom_field_1": "this is some content",
"custom_field_2": "this is some content, too",
"n": "...",
"x5c": "..."
]
}
Using the com.nimbusds.jose.jwk.JWKSet, I'd like to rip through the keys via the getKeys()
method, which gives me com.nimbusds.jose.jwk.JWK objects and read those custom fields. I need to perform some custom logic based on these fields.
Is there a way to do this?
Solution
There does not appear to be a way to deal with this with standard libraries. I was unable to find anything that indicates that a custom parameter in a JWK is legitimate but the Jose library seems to just ignore it. So the only thing I can find is to read it "by hand". Something like:
import com.jayway.jsonpath.JsonPath;
import java.util.HashMap;
import java.util.List;
public class JWKSParserDirect {
private static final String jwks = "{\"keys\": [{" +
"\"kty\": \"RSA\"," +
"\"use\": \"sig\"," +
"\"alg\": \"RS256\"," +
"\"e\": \"AQAB\"," +
"\"kid\": \"2aktWjYabDofafVZIQc_452eAW9Z_pw7ULGGx87ufVA\"," +
"\"x5t\": \"5FTiZff07R_NuqNy5QXUK7uZNLo\"," +
"\"custom_field_1\": \"this is some content\"," +
"\"custom_field_2\": \"this is some content, too\"," +
"\"n\": \"foofoofoo\"," +
"\"x5c\": [\"blahblahblah\"]" +
"}" +
"," +
"{" +
"\"kty\": \"RSA\"," +
"\"use\": \"sig\"," +
"\"alg\": \"RS256\"," +
"\"e\": \"AQAB\"," +
"\"kid\": \"2aktWjYabDofafVZIQc_452eAW9Z_pw7ULGGx87ufVA\"," +
"\"x5t\": \"5FTiZff07R_NuqNy5QXUK7uZNLo\"," +
"\"custom_field_1\": \"this is some content the second time\"," +
"\"custom_field_2\": \"this is some content, too and two\"," +
"\"n\": \"foofoofoo\"," +
"\"x5c\": [\"blahblahblah\"]" +
"}]}";
@SuppressWarnings("unchecked")
public static void main(String[] argv) {
List<Object> keys = JsonPath.read(jwks, "$.keys[*]");
for (Object key : keys) {
HashMap<String, String> keyContents = (HashMap<String, String>) key;
System.out.println("custom_field_1 is \"" + keyContents.get("custom_field_1") + "\"");
System.out.println("custom_field_2 is \"" + keyContents.get("custom_field_2") + "\"");
}
}
}
or, to go direct to the JWK:
import com.jayway.jsonpath.JsonPath;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.List;
public class JWKSParserURL {
@SuppressWarnings("unchecked")
public static void main(String[] argv) {
try {
URL url = new URL("https://someserver.tld/auth/realms/realmname/protocol/openid-connect/certs");
URLConnection urlConnection = url.openConnection();
InputStream inputStream = urlConnection.getInputStream();
List<Object> keys = JsonPath.read(inputStream, "$.keys[*]");
for( Object key: keys) {
HashMap<String, String> keyContents = (HashMap<String, String>)key;
System.out.println("custom_field_1 is \"" + keyContents.get("custom_field_1") + "\"");
System.out.println("custom_field_2 is \"" + keyContents.get("custom_field_2") + "\"");
}
}
catch (IOException ioe) {
ioe.printStackTrace(System.err);
}
}
}
There isn't a way that I can find to have a regex for the Json Path key so you'll need to grab them with the full path. You can also have something like:
List<String> customField1 = JsonPath.read(jwks, "$.key[*].custom_field_1");
to get a list of the "custom_field_1" values. To me this is more difficult as you get all of the custom field values separately and not within each key.
Again, I'm not finding support for custom JWK fields anywhere. JWT - no problem but not JWK. But if you've got this I think you'll need to extract these fields without standard libraries.
Answered By - stdunbar
Answer Checked By - Pedro (JavaFixing Volunteer)