Uploaded image for project: 'OpenAM'
  1. OpenAM
  2. OPENAM-10442

Jwks_uri are cached by issuer instead of client_id

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: Minor
    • Resolution: Duplicate
    • Affects Version/s: 13.5.0, 14.0.0
    • Fix Version/s: None
    • Component/s: oauth2
    • Labels:

      Description

      Description

      To avoid pulling every JWKS_URI content all the time, we cache the values of them into a cache.
      The id of this cache is the issuer name.
      Therefore if you got a client application using the same issuer name for every OAuth2 client agent, then the JWKS_URI used for finding the right JWK would always be the first loaded JWKs_URI, which may be different from the current JWKS_URI.

      An example would be easier to understand

      How to reproduce

      Setup:

      In the Client application side

      • Generate two different JWKs, JWK_A and JWK_B but with JWK_A.kid = JWK_B.kid
      • Generate two different JWKs_URI with different JWKs in it, lets say JWKs_URI_A and JWKS_URI_B. In each JWKS_URI, you will put the right JWK you generated previously

      In the AM side

      • Setup an AM instance with two OpenID agents, Agent_A, Agent_B
      • Configure in Agent_A the JWKS_URI_A and in Agent_B, the JWKS_URI_B

      The issuer name will be always the same, let's say "MrX"

      test:
      1) First request, which will be used to preload the cache

      • Use the JWT as bearer flow for Agent_A and sign with one of the JWK referenced in JWKS_URI_A. (In the JWT, the audience value will be Agent_A)
      • Send the request with OpenAM
        -> AM verifies the JWT with the JWK from JWKS_URI_A and validate the signature
        => you get an access token

      2) Second request, on Agent B, (Now AM has the following cache "MrX" => JWKS_URI_A)

      • Use the JWT as bearer flow for Agent_B and sign with one of the JWK referenced in JWKS_URI_B. (In the JWT, the audience value will be Agent_B)
      • Send the request with OpenAM

      Expected result

      -> AM verifies the JWT with the JWK from JWKS_URI_B and validate the signature
      => you get an access token

      Actual result

      -> AM verifies the JWT with the JWK from JWKS_URI_A instead of JWKS_URI_B and failed.

      • It's loading the JWKS_URI_A instead because of the cache.
      • Then, it tries to find the right JWK from the JWKS_URI_A, a JWK that match the KID specified in the JWT.
      • It will find one because JWK_A.kid will match the current JWT.kid.

      Case with "JWK_A.kid = JWK_B.kid"

      you will probably find pretty extreme the predicate "JWK_A.kid = JWK_B.kid". I took this example a little bit border line to show a situation returning an error instead of an access token (it's easier to understand this problem that way first).
      However, if you remove "JWK_A.kid = JWK_B.kid", you will get a wrong behaviour of AM but more tricky to detect.

      If we come back to our second request analyse with JWK_A.kid != JWK_B.kid:

      AM verifies the JWT with the JWK from JWKS_URI_A instead of JWKS_URI_B and succeed this time. Why?

      • It's loading the JWKS_URI_A instead because of the cache.
      • Then, it tries to find the right JWK from the JWKS_URI_A, a JWK that match the KID specified in the JWT.
      • It won't find one this time and will therefore reload the cache.
      • It will then try the same process with JWKS_URI_B and it will work.

      At the end, you will get a cache "MrX" => JWKS_URI_B

      You can guess that by doing request on Agent A and then Agent B, it will result of a lot of pooling of the JWKS_uri which are not necessary, just because of bad cache miss detection => it's a performance degradation for both AM and the client application.

      How to avoid this situation with AM

      If you got a client application which will use more than one OAuth2 agent, then publish the same JWKS_URI for all of them. Don't try to create a dedicated JWKS_URI for each of them, that's unnecessary.

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                Unassigned
                Reporter:
                quentin.castel Quentin CASTEL [X] (Inactive)
              • Votes:
                0 Vote for this issue
                Watchers:
                5 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: