3

We have an implementation of openid connect which returns an encoded id token, this works well and has been working for a while. However we are attempting to connect to it using cognito in aws and after a bit of trial and error we have found that we are missing a .well-known/openid-configuration file.

This file is meant to contain information about the calls to the openid-connect server we have including the JWK keys.

I don't understand JWK keys, this means: 1. How to generate them 2. Once generated what to do with them? 3. Does the exising code we have for the openid-connect need to change and use the JWK keys? 4. Is there any way of validating an openid-connect configuration?

I have asked something similar a while back but with no avail but revisiting.

Thanks Kevin

What Ive already tried: Been here: https://mkjwk.org/ and clicked on 'New Key', which returns what I assume is a web key.. however don't know what i'm meant to do with it or what the other tabs on that mean.

Expected Results: Expecting AWS Cognito to continue and allow it to connect to our open id connect implementation. Currently just get an error with regards to a missing well known configuration file.

Kevin
  • 383
  • 5
  • 16

2 Answers2

4

The openid connect server you have generates ID token that are JWS. These tokens are signed using a private key (EC, RSA or OKP).

The well-known/openid-configuration is should contain a JSON object that indicates what algorithms are used to sign the tokens and the url to get the public keys associated to the private keys used to sign the token.

For example, the Google Account server configuration indicates the public keys can be found at https://www.googleapis.com/oauth2/v3/certs (jwks_uri parameter).

At this url, you will find a list of keys (JWKSet) formatted in JWK (JSON Web Keys). These formats (JWK and JWKSet) are the standrad representations for keys and key sets used in a JWT context (see RFC7517).

  1. How to generate them

Normally you already have at least one private key to sign your tokens so you don’t have to generate a new one.

  1. Once generated what to do with them?

The private key you have should be a PEM (starting with ------ PRIVATE RSA KEY ----- or similar) or DER key. You just have to convert this key into JWK.

I created a small PHAR application (PHP) that will help to convert your keys. This app is part of the Web Token Framework but can be installed as a standalone app. Make sure you have PHP 7.1, OpenSSL and JSON extensions installed. When the app is installed, you can execute the following command:

jose key:convert:public $(jose key:load:key PATH_TO_YOUR_KEY)

This command will convert the private key into JWK and then convert it from private to public. The result can be shared through the jwks_uri endpoint.

  1. Does the exising code we have for the openid-connect need to change and use the JWK keys?

No. The way you build your tokens does not means you have to change anything.

  1. Is there any way of validating an openid-connect configuration?

As far as I know, there is no tools to validate the configuration object. You have to refer to the OpenID Connect specification.

Community
  • 1
  • 1
Spomky-Labs
  • 15,473
  • 5
  • 40
  • 64
4

While Florent's answer the usage of public key, I like to point you to the specification that defines the contents of JWK and specific implementation details.

OpenID Connect discovery define the discovery document. There you find jwks_uri URL as part of the metadata, which points to JSON Web Key Set

3. OpenID Provider Metadata

wks_uri

REQUIRED. URL of the OP's JSON Web Key Set [JWK] document. This contains the signing key(s) the RP uses to validate signatures from the OP

Now this points to RFC7517 - JSON Web Key (JWK). You can find exact details of each field of the JSON payload there. Refer its samples and appendix section to see sample contents. And your implementation must follow specification requirements defined by this.

For coding, if you are using JAVA, I suggest you to use Nimbus JOSE+JWT library. Sample can be found from this link.

For example, if you already have X509Certificate loaded, then following is the minimalistic code to generate JWK. It is embedded into a Servlet [Full source].

import Common.CertificateLoader;
import Common.Exceptions.FrameworkUncheckedException;
import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.jwk.JWK;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.cert.X509Certificate;

@WebServlet(urlPatterns = "/openid-configuration/jwks_uri")
public class JWKDocument extends HttpServlet {


@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
    // NOTE - LOAD YOUR CERTIFICATE HERE
    final X509Certificate certificate = CertificateLoader.getCertificateLoader().getX509Certificate();

    final JWK jwk;

    try {
        jwk = JWK.parse(certificate);
    } catch (JOSEException e) {
        throw new FrameworkUncheckedException("Error while loading to JWK", e);
    }

    resp.getOutputStream().print(jwk.toJSONString());
  }
}
Community
  • 1
  • 1
Kavindu Dodanduwa
  • 12,193
  • 3
  • 33
  • 46