Skip to content

Enhance OpenID connect configuration to configure prerequisite conditions to apply to let a presented JWT "pass" #2277

@thjaeckle

Description

@thjaeckle

The current OpenID Connect integration does not specifically handle the aud (audience) claim of JWT tokens.

They can of course be used as part of the auth-subjects array, e.g. as:

"{{ jwt:sub }}@{{ jwt:aud }}"

This would however require that all policies in Ditto also contain all of the available audiences in their subjects.
When e.g. adding a new audience, this would require massive migration effort.

I think the aud can be seen as a concept orthogonal to the auth-subjects.
For a configured OpenID Connect provider we would additionally configure the accepted-audiences (which can also be an empty list to accept all aud claims).
Ditto would then check each JWT (directly in the gateway service and without any policy/access control check) of the contained aud is in the list of configured accepted ones.
If not, Ditto can directly respond with a 401 as the token was not "for Ditto" to consume.

I suggest the configuration to be enhanced like this:

ditto.gateway.authentication {
    oauth {
      openid-connect-issuers = {
        myprovider = {
          issuer = "localhost:9000"
          #issuers = [
          #  "localhost:9000/one"
          #  "localhost:9000/two"
          #]
          prerequisite-conditions = [ # prerequisite-conditions must all evaluate to true (AND semantics)
            "{{ jwt:aud | fn:filter('eq','prod|qa') }}",
            "{{ fn:filter(jwt:tenant,'like','Acme*') }}"
          ]
          auth-subjects = [
            "{{ jwt:sub }}",
            "{{ jwt:sub }}/{{ jwt:scp }}",
            "{{ jwt:sub }}/{{ jwt:scp }}@{{ jwt:client_id }}",
            "{{ jwt:sub }}/{{ jwt:scp }}@{{ jwt:non_existing }}",
            "{{ jwt:roles/support }}"
          ]
          inject-claims-into-headers = {
            user-email = "{{ jwt:email }}"
            user-name = "{{ jwt:name }}"
          }
        }
      }
    }
}

The added prerequisite-conditions hold a list of making use of Ditto placeholder function fn:filter

  • starting with a supported placeholder
  • when the condition "retains" any matches (fn:filter removes all non-matches)
  • the condition is fulfilled

This lets Ditto easily and very cheaply reject JWTs for which e.g. an unexpected aud claim was presented.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions