OIDC Login Problem

After updating from 8.15.3 to 8.16.1 today, we found we were unable to login to Kibana via our SSO server. Instead we got the message "We hit an authentication error".

After a bunch of digging, I eventually found an error in the logs on one of our nodes:

"Authentication to realm oidc1 failed - Failed to authenticate user with OpenID Connect (Caused by org.elasticsearch.ElasticsearchSecurityException: Failed to retrieve remote JWK set.; Caused by java.text.ParseException: Invalid JWK at position 0: Unexpected type of JSON object member with key exp)"

Editing the jwk handler to remove the exp field from the keys objects in the JSON did indeed resolve our login problem.

I guess an oidc library got updated in the newer release and I missed it in the release notes.

Adding it here, so if someone else runs into the same issue they now have the fix. Assuming they control the OIDC server side output.

1 Like

@cafuego Could you share an example of a JWK which caused the parse error?

The Nimbus OIDC SDK dependency has been upgraded in 8.16.0 and I suspect that the change in the SDK to use gson may have caused this. I'm suspecting that exp parsing failed due to an either null or invalid type (e.g. string instead of number).

@slobodanadamovic Yes, here is a truncated version:

{
  "keys": [
    {
      "e": "AQAB",
      "n": "m13CI5aQt8F9yo8GEjxhGg9B...",
      "mod": "m13CI5aQt8F9yo8...",
      "exp": "AQAB",
      "x5c": [
        "MIIC+jCCAeKgA..."
      ],
      "kty": "RSA",
      "use": "sig",
      "alg": "RS256",
      "kid": "8N_Uyn8By94Lb0dDCD..."
    }
  ]
}

So exp is definitely a string. Just outright dropping it from the JSON fixed the issue; I had a quick look at an OKTA jwk blob and they didn't have an exp either. Doing that seems to have not broken anything.

A bit more searching shows that it's an optional boolean, not a string, so my current plan is to upstream modify the Drupal module that generated this JWK. It simply copies the e value to exp and that's clearly wrong.

Thanks for providing the example. The exp field is optional expiry time of RSA keys. It's quite easy to mix e and exp fields.

The value must be an integer (not boolean) which represents a number of seconds since the Unix epoch. The upgraded SDK library is now being stricter while parsing JWKS JSONs.