diff --git a/internal/outpost/proxyv2/application/mode_common.go b/internal/outpost/proxyv2/application/mode_common.go index b0dac258d9..5438b0e361 100644 --- a/internal/outpost/proxyv2/application/mode_common.go +++ b/internal/outpost/proxyv2/application/mode_common.go @@ -76,6 +76,7 @@ func (a *Application) getTraefikForwardUrl(r *http.Request) *url.URL { a.log.WithError(err).Warning("Failed to parse URL from traefik") return r.URL } + a.log.WithField("url", u.String()).Trace("traefik forwarded url") return u } diff --git a/internal/outpost/proxyv2/application/oauth.go b/internal/outpost/proxyv2/application/oauth.go index b747e8182c..9542d64561 100644 --- a/internal/outpost/proxyv2/application/oauth.go +++ b/internal/outpost/proxyv2/application/oauth.go @@ -10,10 +10,14 @@ import ( ) func (a *Application) handleRedirect(rw http.ResponseWriter, r *http.Request) { - state := base64.RawStdEncoding.EncodeToString(securecookie.GenerateRandomKey(32)) - s, _ := a.sessions.Get(r, constants.SeesionName) - s.Values[constants.SessionOAuthState] = state - err := s.Save(r, rw) + newState := base64.RawStdEncoding.EncodeToString(securecookie.GenerateRandomKey(32)) + s, err := a.sessions.Get(r, constants.SeesionName) + if err != nil { + s.Values[constants.SessionOAuthState] = []string{} + } + state := s.Values[constants.SessionOAuthState].([]string) + s.Values[constants.SessionOAuthState] = append(state, newState) + err = s.Save(r, rw) if err != nil { a.log.WithError(err).Warning("failed to save session") } @@ -24,7 +28,7 @@ func (a *Application) handleRedirect(rw http.ResponseWriter, r *http.Request) { return } } - http.Redirect(rw, r, a.oauthConfig.AuthCodeURL(state), http.StatusFound) + http.Redirect(rw, r, a.oauthConfig.AuthCodeURL(newState), http.StatusFound) } func (a *Application) handleCallback(rw http.ResponseWriter, r *http.Request) { @@ -35,7 +39,7 @@ func (a *Application) handleCallback(rw http.ResponseWriter, r *http.Request) { http.Redirect(rw, r, a.proxyConfig.ExternalHost, http.StatusFound) return } - claims, err := a.redeemCallback(r, state.(string)) + claims, err := a.redeemCallback(r, state.([]string)) if err != nil { a.log.WithError(err).Warning("failed to redeem code") rw.WriteHeader(400) @@ -61,6 +65,7 @@ func (a *Application) handleCallback(rw http.ResponseWriter, r *http.Request) { redirect := a.proxyConfig.ExternalHost redirectR, ok := s.Values[constants.SessionRedirect] if ok { + a.log.WithField("redirect", redirectR).Trace("got final redirect from session") redirect = redirectR.(string) } http.Redirect(rw, r, redirect, http.StatusFound) diff --git a/internal/outpost/proxyv2/application/oauth_callback.go b/internal/outpost/proxyv2/application/oauth_callback.go index acd66cf313..1ae8681efb 100644 --- a/internal/outpost/proxyv2/application/oauth_callback.go +++ b/internal/outpost/proxyv2/application/oauth_callback.go @@ -8,10 +8,19 @@ import ( "golang.org/x/oauth2" ) -func (a *Application) redeemCallback(r *http.Request, shouldState string) (*Claims, error) { +func (a *Application) redeemCallback(r *http.Request, states []string) (*Claims, error) { state := r.URL.Query().Get("state") - if state == "" || state != shouldState { - return nil, fmt.Errorf("blank/invalid state") + if len(states) < 1 { + return nil, fmt.Errorf("no states") + } + found := false + for _, fstate := range states { + if fstate == state { + found = true + } + } + if !found { + return nil, fmt.Errorf("invalid state") } code := r.URL.Query().Get("code")