outposts/proxy: add support for multiple states, when multiple requests are redirect at once

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens Langhammer 2021-12-26 14:11:11 +01:00
parent f93f7e635b
commit 410d1b97cd
3 changed files with 24 additions and 9 deletions

View File

@ -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
}

View File

@ -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)

View File

@ -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")