louketo / louketo-proxy

A OpenID / Proxy service
Apache License 2.0
950 stars 343 forks source link

Redirection URL path prefix #686

Open JeremyMahieu opened 3 years ago

JeremyMahieu commented 3 years ago

Redirection URL path

Summary

I use traefik as a reverse proxy. My different services are differentiated by path.

I want service 1 to use keycloak authentication so I used the following:

redirection-url: http://my.domain.com/service1
secure-cookie: false

When I visit http://my.domain.com/service1 it redirects to http://my.domain.com/oauth/authorize?state=(...). However it should redirect to http://my.domain.com/service1/oauth/authorize?state=(...)

Environment

Expected Results

Get redirected to http://my.domain.com/service1/oauth/authorize?state=(...)

Actual Results

Got redirected to http://my.domain.com/oauth/authorize?state=(...)

Additional Information

Due to reasons I'm forced to use paths. Only my.domain.com is available on one port. Everything is actually https but traefik offloads tls so the app only sees http. I can strip the /service1 prefix with traefik once traefik has determined which service this request belongs so so the actual requested endpoints will match up but the redirect needs to be correct.

johnhieu commented 3 years ago

I have the same problem with the /oauth/authorize with Traefik with your setup.

Unfortunately, the /oauth/authorize won't use the Redirection URL to redirect it. The source code for this is specified below `

// WithOAuthURI returns the oauth uri
func (r *Config) WithOAuthURI(uri string) string {
    if r.BaseURI != "" {
        return fmt.Sprintf("%s/%s/%s", r.BaseURI, r.OAuthURI, uri)
    }

    return fmt.Sprintf("%s/%s", r.OAuthURI, uri)
}

The only way to make it to redirect correctly is to use the base-uri variable. In my case, I have to design a custom variable for the Traefik because the base-uri will also affect how cookies will be stored.

jenwirth commented 3 years ago

@johnhieu what do you mean when you say "I have to design a custom variable for the Traefik"?

I think i have a related problem:

environment k8s/ingress nginx that rewrites path: /sample(/|$)(.*) to nginx.ingress.kubernetes.io/rewrite-target: /$2

How did you get it to work?

tx.,

johnhieu commented 3 years ago

@johnhieu what do you mean when you say "I have to design a custom variable for the Traefik"?

I think i have a related problem:

environment k8s/ingress nginx that rewrites path: /sample(/|$)(.*) to nginx.ingress.kubernetes.io/rewrite-target: /$2

  • with --base-uri=/sample i get into a redirect loop (i guess this has to do with the cookies)
  • without --base-uri it redirects without the /sample (i do have my nginx controller set x-forwarded-prefix, but its ignored)

How did you get it to work?

tx.,

Thanks for asking and sorry for the delayed response. I am not at good at explaining things but I try my best to explain. When I mentioned the custom variable, the variable is added in this configuration (link).

What I did was to modify these files:

doc.go - Added TraefikAPIURI variable

        BaseURI string `json:"base-uri" yaml:"base-uri" usage:"common prefix for all URIs" env:"BASE_URI"`
    // OAuthURI is the uri for the oauth endpoints for the proxy
    OAuthURI string `json:"oauth-uri" yaml:"oauth-uri" usage:"the uri for proxy oauth endpoints" env:"OAUTH_URI"`
    // TraefikProxyPath is the uri for the authorize endpoint since /oauth/authorize does not include Traefik path as a base address
    TraefikAPIURI string `json:"traefik-api-uri" yaml:"traefik-api-uri" usage:"the uri for /oauth/authorize endpoints" env:"TRAEFIK_API_URI"`
    // Scopes is a list of scope we should request
    Scopes []string `json:"scopes" yaml:"scopes" usage:"list of scopes requested when authenticating the user"`
    // Upstream is the upstream endpoint i.e whom were proxying to

handlers.go - added a custom code to use the variable specified in the above configuration inside oauthCallbackHandler function (should be at line 104)

    if r.config.TraefikAPIURI != "" {
        redirectURI = fmt.Sprintf("/%s%s", r.config.TraefikAPIURI, redirectURI)
    }

    r.redirectToURL(redirectURI, w, req, http.StatusSeeOther)

With this variable, I can add the path prefix and make sure Keycloak Gatekeeper will add that path prefix when redirecting back to the /oauth/authorize URL, as described by the OP's expectation for the URL.

jenwirth commented 3 years ago

Thanks, i get it. Thanks for your explanation :)

For now i am trying a different path (istio with oauth2-proxy). I might abandon that path and return to louketo-proxy. It seems however this project is EOL. This means i will have to move at one time anyway. (FYI oauth2-proxy as a sidecar proxy, was also not able to work with a path prefix. Hope to get more luck by combining Envoy and oauth2-proxy.

Can't understand why this has to be soo difficult :(

Thanks again

johnhieu commented 3 years ago

It's unfortunate to see that the project is EOL. I am still watching the thread to see anyone stepping up to maintain this project. There are people talking about continuing the project so let's hope that this project will be on-going.

I have tried other repo like oauth2-proxy, etc but none of them seems to work well with a path prefix, only Keycloak Gatekeeper seems to support but there are limitations as well. That's why I had to design a solution and fork the project to our private server.

Hopefully, someone will take over the project.

Cheers, and you're welcome.