Hi,
I have setup a test environment with oauth2-proxy ,dex and istio 1.9.1 to test the ext_authz functionality.
All code can be found here : istio-on-kind/mesh.yaml at 4178bad9614de33d1b215d7c0cb7fe32ad08b839 · primeroz/istio-on-kind · GitHub
This is almost working other than the final redirect to the original URL Requested
- setup the cluster as described in README.md
- visit http://podinfo.127.0.0.1.nip.io
- get redirected to dex by istio ingress due to oauth2-proxy and the request no having the cookie
- authenticate with
admin@example.com
and password
- client get redirected to
oauth2-proxy.127.0.0.1/oauth2/callback
and the client is presented an authenticated page
-
here i would expect to get redirected to the original url
http://podinfo.127.0.0.1.nip.io
but instead you only get the oauth2-proxy Authenticated
Page
- visit the URL
http://podinfo.127.0.0.1.nip.io
again
- client has the cookie, oauth2-proxy return 200 to istio and the request is forwarded to the usptream workload
Is it actually possible to get it to work all in one shot ?
Configuration Snippets
MeshConfig
extensionProviders:
- name: "oauth2-proxy"
envoyExtAuthzHttp:
service: "oauth2-proxy.dex.svc.cluster.local"
port: "4180" # The default port used by oauth2-proxy.
#includeHeadersInCheck: ["authorization", "cookie"] # headers sent to the oauth2-proxy in the check request.
includeHeadersInCheck: # headers sent to the oauth2-proxy in the check request.
# https://github.com/oauth2-proxy/oauth2-proxy/issues/350#issuecomment-576949334
- "cookie"
- "x-forwarded-access-token"
- "x-forwarded-user"
- "x-forwarded-email"
- "authorization"
- "x-forwarded-proto"
- "proxy-authorization"
- "user-agent"
- "x-forwarded-host"
- "from"
- "x-forwarded-for"
- "accept"
headersToUpstreamOnAllow: ["authorization", "path", "x-auth-request-user", "x-auth-request-email", "x-auth-request-access-token", "x-auth-request-user-groups"] # headers sent to backend application when request is allowed.
headersToDownstreamOnDeny: ["content-type", "set-cookie"] # headers sent back to the client when request is denied.
OAUTH proxy is configured as
- --http-address=0.0.0.0:4180
- --email-domain="example.com"
- --cookie-refresh=1h
- --cookie-secure=false # Set to false for test environment only
- --set-xauthrequest=true # X-Auth-Request-User, X-Auth-Request-Email, X-Auth-Request-Preferred-Username, X-Auth-Request-Groups
- --pass-access-token=true # X-Auth-Request-Access-Token, must first enable --set-xauthrequest
- --set-authorization-header=true # Authorization: Bearer <JWT>
- --pass-authorization-header=true # pass OIDC IDToken to upstream via Authorization Bearer header
- --pass-host-header=true # pass the request Host Header to upstream
- --pass-access-token=true # pass OAuth access_token to upstream via X-Forwarded-Access-Token header. When used with --set-xauthrequest this adds the X-Auth-Request-Access-Token header to the response
- --upstream=static://200
- --reverse-proxy
#- --whitelist-domain=".127.0.0.1.nip.io"
- --whitelist-domain=".127.0.0.1.nip.io"
- --cookie-domain=".127.0.0.1.nip.io"
- --cookie-name=_oauth2_proxy
- --cookie-samesite=lax
#- --scope="openid groups profile email"
- --provider=oidc
- --oidc-issuer-url=http://dex.127.0.0.1.nip.io
- --redirect-url=http://oauth2-proxy.127.0.0.1.nip.io/oauth2/callback
- --skip-provider-button=true
and the AuthPolicy
---
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: podinfo
#namespace: dev
# Does it need to be in the ingrassgateway namespace?
namespace: istio-system
spec:
selector:
matchLabels:
app: istio-ingressgateway
action: CUSTOM
provider:
name: "oauth2-proxy"
rules:
- to:
- operation:
hosts:
- "podinfo.127.0.0.1.nip.io"
1 Like
For reference:
The issue was with setting - --redirect-url=http://oauth2-proxy.127.0.0.1.nip.io/oauth2/callback
without that the callback will be to the original HOST/oauth2/callback which envoy will forward to oauth2-proxy for validation and then back to the original HOST
cc @YangminZhu regarding to external authz.
@YangminZhu I’m seeing a similar issue attempting to configure oauth2-proxy as an external authorization provider: The original request to an authaurizationpolicy-protected service gets successfully redirected to the oauth2-proxy, I’m able to authenticate, and the redirect goes back to the oauth2-proxy.
The problem is, oauth2-proxy requires one of the following to be configured on the request in order to correctly redirect the original request back to the original host:
-
rd
querysting parameter
-
X-Auth-Request-Redirect
header
-
X-Forwarded-(Proto|Host|Uri)
headers (when ReverseProxy mode is enabled)
-
X-Forwarded-(Proto|Host)
if Uri
has the ProxyPath (i.e. /oauth2/*)
-
X-Forwarded-Uri
direct URI path (when ReverseProxy mode is enabled)
-
req.URL.RequestURI
if not under the ProxyPath (i.e. /oauth2/*)
Clearly these headers do not exist on the ext_authz initiated requests to the oauth2-proxy, and therefore the oauth2-proxy does not redirect. Are you aware of any solutions to configure the redirect correctly?
oauth2-proxy config:
provider = "oidc"
whitelist_domain = ".internal.com"
cookie_domain = ".internal.com"
redirect_url = "https://oauth2-proxy-url.com/oauth2/callback"
oidc_issuer_url = "https://x.okta.com/oauth2/default"
email_domains = [
"*"
]
upstreams = [ "static://200" ]
pass_access_token = true
skip_provider_button = true
set_authorization_header = true
pass_authorization_header = true
pass_host_header = true
set_xauthrequest = true
skip_jwt_bearer_tokens = false
reverse_proxy = true
cookie_name = "_oauth2_proxy"
cookie_samesite = "lax"
standard_logging = true
auth_logging = true
request_logging = true
session-cookie-minimal = true
Mesh config:
meshConfig:
# Add the following content to define the external authorizers.
extensionProviders:
- name: "oauth2-proxy"
envoyExtAuthzHttp:
service: "oauth2-proxy.auth.svc.cluster.local"
port: "80" # The default port used by oauth2-proxy.
includeHeadersInCheck: # headers sent to the oauth2-proxy in the check request. https://github.com/oauth2-proxy/oauth2-proxy/issues/350#issuecomment-576949334
- "cookie"
- "x-forwarded-access-token"
- "x-forwarded-user"
- "x-forwarded-email"
- "authorization"
- "x-forwarded-proto"
- "proxy-authorization"
- "user-agent"
- "x-forwarded-host"
- "from"
- "x-forwarded-for"
- "x-forwarded-uri"
- "x-auth-request-redirect"
- "accept"
headersToUpstreamOnAllow: ["authorization", "path", "x-auth-request-user", "x-forwarded-uri", "x-auth-request-redirect", "x-auth-request-email", "x-auth-request-access-token", "x-auth-request-user-groups"] # headers sent to backend application when request is allowed.
headersToDownstreamOnDeny: ["content-type", "set-cookie"] # headers sent back to the client when request is denied.
1 Like
The following did the trick for me (note the includeAdditionalHeadersInCheck
entry):
extensionProviders:
- envoyExtAuthzHttp:
headersToDownstreamOnDeny:
- content-type
- set-cookie
headersToUpstreamOnAllow:
- authorization
- cookie
includeAdditionalHeadersInCheck:
X-Auth-Request-Redirect: 'https://%REQ(Host)%'
includeHeadersInCheck:
- authorization
- cookie
port: 4180
service: oauth2-proxy.istio-system.svc.cluster.local
name: oauth2-proxy
This effectively adds another header, X-Auth-Request-Redirect
, to the request that gets forwarded to oauth2-proxy
. The value of this header is extracted from the pre-existing Host
header.
@djfinnoy thanks for the pointer - I’ve tried updating to istio 1.10 and configuring includeAdditionalHeadersInCheck
as you’ve suggested. I’m seeing that the X-Auth-Request-Redirect
header does get attached on authentication, but the HOST is set to the oauth2-proxy url, not the original HOST.
If possible, would you mind sharing your oauth2-proxy deployment configuration and istio AuthorizationPolicy?
I posted my setup in a separate thread: Adding headers for oauth2-proxy redirect
Check the oauth2-proxy logs now that you’ve got a redirect header, if there are any issues with your redirect URL it will be posted there (note that protocol and quotation marks are required, eg 'https://%REQ(Host)%'
).
Out of curiosity, how are you seeing the headers sent to oauth2-proxy? They don’t show up in my in my browser.
@djfinnoy Thanks for sharing your config! I’ve ensured I’m using quotes in my Istio Operator definition (as you’ve suggested).
One thing I noticed is that you’re not configuring oauth2-proxy’s redirect_url (which I am currently doing in my config). Is this intentional? If so, how do you define the accepted redirect_urls on your Oauth application (looks like you’re using github)?
Ok - I finally have this working - it seems to have been an issue with the version of oauth2-proxy I was using (originally v5.x). Since updating to v7, the redirect works correctly with istio 1.10
glad you got it working.
I am in fact using --redirect-url
, but it appears I accidentally cropped that out of my code example.
without it, the auth flow fails; tested this with both GitHub and Google as the oauth provider.
Thanks for this tip. I noticed the redirect was still landing at the root, for example starting the flow by visiting https://bookinfo.example.com/productpage results in being redirected to https://bookinfo.example.com after authentication.
The following configuration includes the scheme, authority (host:port), path and query parameters. I don’t think it includes anchor fragments though.
includeAdditionalHeadersInCheck:
X-Auth-Request-Redirect: '%REQ(x-forwarded-proto)%://%REQ(:authority)%%REQ(:path)%'
3 Likes
Hey Jeff,
Did you need a separate gateway and/or virutalservice for your oauth2-proxy? Is your OIDC’s redirect uri pointing to your oauth2-proxy’s domain?
Yes, oauth2-proxy needs to be accessible by the end-user’s browser for the redirect to hand off the token to oauth2-proxy. I’ve used both separate Gateway resources with distinct hosts and also one Gateway host with VirtualService resources to route paths for the IDP and external authorizer.
FYI, this gets complex pretty fast. There are pitfalls with making sure httpsRedirect: true keeps working as expected while also preserving compatibility with cert-manager. I’m available for contract work if you’d like help. https://openinfrastructure.co/