0

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?

el n00b
  • 1,957
  • 7
  • 37
  • 64

1 Answers1

1

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.

stdunbar
  • 16,263
  • 11
  • 31
  • 53
  • That's really close to the workaround I wrote. I am just pulling the custom fields into a cache using the `kid` or the hash of the doc if there is no `kid`. Ugh. – el n00b Sep 27 '22 at 15:39