navikt / mock-oauth2-server

A scriptable/customizable web server for testing HTTP clients using OAuth2/OpenID Connect or applications with a dependency to a running OAuth2 server (i.e. APIs requiring signed JWTs from a known issuer)
MIT License
248 stars 59 forks source link

Extend replaceVariables functionality to work with objects in claims #674

Closed wallacekelly-da closed 5 months ago

wallacekelly-da commented 7 months ago

Repro steps

Motivated by this, define a request mapping in the JSON config file:

{
  "tokenCallbacks": [
    {
      "issuerId": "mockauth",
      "tokenExpiry": 120,
      "requestMappings": [
        {
          "requestParam": "mock_token_type",
          "match": "custom",
          "claims": {
            "https://daml.com/ledger-api": {
              "participantId": "${participantId}",
              "actAs": [ "${actAs}" ],
              "readAs": [ "${readAs}" ]
            }
          }
        }
      ]
    }
  ]
}

Desired Behavior

The mock-oauth2-server responds to token requests with a signed token with ${participantId}, ${actAs}, and ${readAs} replaced with values from the token request. Here is a sample of what I'm looking for:

{
  "https://daml.com/ledger-api": {
    "participantId": "participant1::1220f7994746f8f05198bbaf817714503d54fa17f4b23f17fafae8387f86bf5eaead",
    "actAs": [ "admin::1220f7994746f8f05198bbaf817714503d54fa17f4b23f17fafae8387f86bf5eaead" ],
    "readAs": [ "admin::1220f7994746f8f05198bbaf817714503d54fa17f4b23f17fafae8387f86bf5eaead" ]
  },
  "nbf": 1714423520,
  "iss": "http://localhost:8080/mockauth",
  "exp": 1714423640,
  "iat": 1714423520,
  "jti": "3693514f-0f72-4db2-8584-ebab4d5924c7"
}

Current Behavior

The fields ${participantId}, ${actAs}, and ${readAs} are not replaced. Here is an example of what is returned:

{
  "https://daml.com/ledger-api": {
    "participantId": "${participantId}",
    "actAs": [ "${actAs}" ],
    "readAs": [ "${readAs}" ]
  },
  "nbf": 1714423520,
  "iss": "http://localhost:8080/mockauth",
  "exp": 1714423640,
  "iat": 1714423520,
  "jti": "3693514f-0f72-4db2-8584-ebab4d5924c7"
}

Related code

It looks like the replaceVariables function is only being applied to the first-level strings and lists of strings.

From OAuth2TokenCallback.kt:

when (value) {
    is String -> replaceVariables(value, variables)
    is List<*> ->
        value.map { v ->
            if (v is String) {
                replaceVariables(v, variables)
            } else {
                v
            }
        }
    else -> value
}

This code would need to be updated to recurse the fields of child objects. Or, perhaps more simply, perform the substitution on the full claims JSON string, instead of the individual claims.

tommytroen commented 7 months ago

@wallacekelly-da are the parameters participantId, actAs, readAs part of the token request? The only way we can use dynamic values in the returned token for a specific request mapping is if we receive them as a part of the token request. Can you provide a sample of the token request?

wallacekelly-da commented 7 months ago

Hi, @tommytroen! Thanks for asking:

 curl http://localhost:8080/mockauth/token \
  -d grant_type=client_credentials \
  -d client_id="ignored" \
  -d client_secret="ignored" \
  -d mock_token_type="custom" \
  -d participantId="participant1::1220f7994746f8f05198bbaf817714503d54fa17f4b23f17fafae8387f86bf5eaead" \
  -d actAs="admin::1220f7994746f8f05198bbaf817714503d54fa17f4b23f17fafae8387f86bf5eaead" \
  -d readAs="admin::1220f7994746f8f05198bbaf817714503d54fa17f4b23f17fafae8387f86bf5eaead"
tommytroen commented 7 months ago

@wallacekelly-da: Great thanks, this looks feasible. Will have a look soon.

ybelMekk commented 5 months ago

seems like this to are related? https://github.com/navikt/mock-oauth2-server/issues/683

tommytroen commented 5 months ago

@wallacekelly-da sorry for taking so long, we have create a PR here, #699 , which should support your use case.

tronghn commented 5 months ago

Fixed in https://github.com/navikt/mock-oauth2-server/pull/699

wallacekelly-da commented 4 months ago

I have been using this today and it works great! Thanks, @tommytroen !