gateway
gateway copied to clipboard
Filters for OIDC authentication mechanisms
Description:
Currently, when OIDC and JWT authentication mechanisms are configured in the same SecurityPolicy, the OIDC is applied first. It ensures the presence of the bearer and refresh tokens in cookies, and adds the Authorisation header to the request. Then JWT is applied, validating the added header.
This setup works perfectly for browser requests. However, it prevents monitoring systems and regression tests, which provide a valid Authorisation header in the requests, from accessing the services on the same URLs. The OIDC mechanism kicks in first and redirects the requests to the login pages because of the missing cookies.
We suggest extending the configuration of, at least, the OIDC mechanism with the possibility of adding a header-based filter.
When implemented, the OIDC can be skipped if the Authorization header is present.
An example of the configuration:
oidc:
provider: {}
clientID: ""
scopes: []
clientSecret: {}
matches:
- ifRequestHeader:
name: Authorization
valueRegex: Bearer.*
onMatch: skip
Envoy Proxy supports Composite Filters, which support such decisions and therefore can be used to implement this functionality.
Relevant Links:
- The Combining OIDC and JWT authentication discussion
- Envoy Composite Filters
@arkodg any comments to this one? As I see this is quite important feature to have possibility to use service with human users and machines.
@zetaab @sadovnikov my hesitance is with including another field like matches within oidc . Today the request is matching header attributes defined within the HTTPRoute and the SecurityPolicy is applied to a HTTPRoute. Adding another matches within oidc is not required and may confuse the user.
You could implement the same logic (https://github.com/envoyproxy/gateway/discussions/2425#discussioncomment-8141456) with 2 HTTPRoutes today
- Security Policy 1 with a
oidcconfig that applies to a HTTPRoute1 which has your routing rules - Security Policy 2 with a
jwtconfig that applies to a HTTPRoute2 which has your routing rules along with extra matches such asBearerTokenis set &&OauthHMACis empty &&OauthExpiresis empty (will take precedence to the extra matches)
This should unblock you for now, but will end up causing some duplicate configuration for you.
You could also use a EnvoyPatchPolicy with a pass_through_matcher defined in https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/http/oauth2/v3/oauth.proto#extensions-filters-http-oauth2-v3-oauth2config
A more long term would be to to figure out the right UX / field for this use case.
@arkodg From my discussion with @zhaohuabing I understood that two HTTP Routes cannot be applied to the same host/path. It seems I read it wrong, it's just necessary to ensure the uniqueness of the "matches" in the routes. We'll give it a try
This issue has been automatically marked as stale because it has not had activity in the last 30 days.
here is the example of how it can be used currently https://gist.github.com/zetaab/31b835bfed5bdc7b2a3e29bc6557e3c1
What that does?
- it can have public paths which is allowed to everyone
- it have /login path which will make the OIDC flow for humans and create cookies
- /api path which will work for both: humans (with cookie) and machines (with bearer token) (with two different identity providers)
However, if its used like this it means that application should have the logic to redirect to /login when its needed to use refresh token / create new token.
tl;dr it works but its not pretty
This issue has been automatically marked as stale because it has not had activity in the last 30 days.