Sporadic "No matching keys"

Issue #182 resolved
Former user created an issue

I've been running a simple test class to test Yahoo OpenId Connect Id Token verification. And it works great but about one out of 5 times I run it (tried several networks), I get a "No matching keys" -- on the same Id token!

Comments (18)

  1. Michael Bell

    To be specific

    nimbusds.jose.proc.BadJOSEException: Signed JWT rejected: No matching key(s) found

  2. Mike Bell

    Minute or two. I was just tuning an oauth flow from eclipse then breakpoint ignore right after token exchange and step through. Also ran through without debugging happened about fifty percent of the time after a while.

  3. Connect2id OSS

    The ID token in your code has got the following header:

    {
      "alg": "ES256",
      "kid": "3466d51f7dd0c780565688c183921816c45889ad"
    }
    

    The matching key is apparently present in the published JWK set (checked at 10am GMT), where we see one RSA key and one EC key:

    {
       "keys" : [
          {
             "x" : "cWZxqH95zGdr8P4XvPd_jgoP5XROlipzYxfC_vWC61I",
             "crv" : "P-256",
             "use" : "sig",
             "kid" : "3466d51f7dd0c780565688c183921816c45889ad",
             "alg" : "ES256",
             "kty" : "EC",
             "y" : "AK8V_Tgg_ayGoXiseiwLOClkekc9fi49aYUQpnY1Ay_y"
          },
          {
             "kid" : "6ff94cdad11e7c3ac08dc9ec3c44844b87e364f7",
             "n" : "AL1LkSgnGk-sKqFDBrojoqvpqOwmN7tgvz0p6J9g8O_nOzXMAwzMUUs4H_FMgeNWcuE6XzJX3spVwAYBp-rBLwyXXCGbO_chhwcpBDNndlZyqS2zOvwmZYdh4MhrUnIOcA8cdDB1hqoDdKOx9M-EjuoafcgqEPA7rWsZTH6TITMP",
             "use" : "sig",
             "e" : "AQAB",
             "alg" : "RS256",
             "kty" : "RSA"
          }
       ]
    }
    

    I'll double check your code, and also see how often they rotate the keys. The RemoteJWKSource should handle key rotation automatically for you. It also has key caching, to speed up processing.

  4. Connect2id OSS

    Hi Michael,

    I observed one HTTP read timeout when running the code (on the 1st iteration). The default RemoteJWKSource sets a HTTP read timeout of 250ms. I'll run a few more tests.

  5. Connect2id OSS

    I suspect your exception is caused due to a slow connection (WiFi?) to the Yahoo servers.

    Revised the RemoteJWKSet by raising the default timeouts to 1 second, and adding a getter for the latest neworking exception (if any) -> e088d3f

    Will be released shortly as v4.18.

    Let us know how this works out.

    Cheers,

  6. Michael Bell

    Thanks, I switched to another SDK so hadn't had the chance to test. Neither 250ms nor 1 s seems honestly reasonable for a caching url system, but that's your call. Also I question that there was no sign of an issue in the url fetching either via exception or error code or observer.

    I would strongly recommend at least an observer being added to that class such that folks can see onRetrievalSucceeded, onRetrievalFailed, etc

  7. Connect2id OSS

    Hi Michael,

    We couldn't reproduce the condition, unless there was a HTTP read time out. What kind of connection were you using for the tests?

    The observer is a good idea, thanks!

  8. Michael Bell

    A Wifi connection indeed. I guess I expected if there was an issue I'd know about it. I was simply running the server in DEBUG mode in eclipse, generating a new URL for initiating oauth and pasting in browser. It would then callback to the ngrok hosted server, and I'd hit a breakpoint shortly after exchanging the code for the access/refresh/id tokens. I found a fairly steady rate of intermittent failures doing this. As you can see from the code, the cache is initialized only once (although of course this wouldn't help much in this case, since the code was generally run only once before rerunning). and then I'd hit that nasty exception.

    Honestly I hadn't even thought of the connection issue (reasonable theory as it is), from the message I merely assumed it was an algorithm issue. (I did note loading yahoos cert page that the ORDER of the keys changes, although of course that shouldn't matter). I suppose I could have temporarily hard coded the strings, but I was in a hurry, tried another SDK, it worked, and finished off.

    Anyway, it was VERY easy to repro here, which does tend to support your Wifi theory. The only partial counter theory is it failed at home too (which was yes a Wifi, but another connection)

  9. Michael Bell

    Here's a suggestion (another) - besides an observer, consider throwing a SUBCLASS of the regular JoseException, Something like FailedToLoadRemoteCacheException..

    That would have made it MUCH easier to recognize ;)

  10. Connect2id OSS

    Thanks Michael, we'll consider all these suggestions!

    Working with observers will probably require some synchronization if the code is run in a multithreaded environment. The exception seems to be the better approach here.

    Which SDK did you settle on?

  11. Michael Bell

    You probably don't need synchronization if you use a CopyOnArrayList - they are perfect for lockless observer iteration. Depends on what you tell the observer of course, but if its just an exception or immutable data.

    Anyway, I grabbed jose4j and so far it works pretty well. I must say as a point of counter feedback that I preferred your validator callback but liked their fluent builder a lot for getting the basics done quickly. Other than that it seemed pretty comparable on the surface.

  12. Connect2id OSS

    Jose4j is a fine library, we use it in our automated interop tests.

    Thanks again for your feedback and happy coding!

  13. Log in to comment