providers/proxy: rework redirect mechanism (#8594)

* providers/proxy: rework redirect mechanism

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* add session id, don't tie to state in session

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* handle state failing to parse

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* save session after creating state

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* remove debug

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* include task expiry in status

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix redirect URL detection

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix tests

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
Jens L
2024-05-06 03:07:08 +02:00
committed by GitHub
parent 3e4fea875a
commit c45bb8e985
16 changed files with 272 additions and 190 deletions

View File

@ -3,22 +3,43 @@ package application
import (
"context"
"fmt"
"net/http"
"net/url"
"time"
log "github.com/sirupsen/logrus"
"goauthentik.io/internal/outpost/proxyv2/constants"
"golang.org/x/oauth2"
)
func (a *Application) redeemCallback(savedState string, u *url.URL, c context.Context) (*Claims, error) {
state := u.Query().Get("state")
a.log.WithFields(log.Fields{
"states": savedState,
"expected": state,
}).Trace("tracing states")
if savedState != state {
return nil, fmt.Errorf("invalid state")
func (a *Application) handleAuthCallback(rw http.ResponseWriter, r *http.Request) {
state := a.stateFromRequest(r)
if state == nil {
a.log.Warning("invalid state")
a.redirect(rw, r)
return
}
claims, err := a.redeemCallback(r.URL, r.Context())
if err != nil {
a.log.WithError(err).Warning("failed to redeem code")
a.redirect(rw, r)
return
}
s, err := a.sessions.Get(r, a.SessionName())
if err != nil {
a.log.WithError(err).Trace("failed to get session")
}
s.Options.MaxAge = int(time.Until(time.Unix(int64(claims.Exp), 0)).Seconds())
s.Values[constants.SessionClaims] = &claims
err = s.Save(r, rw)
if err != nil {
a.log.WithError(err).Warning("failed to save session")
rw.WriteHeader(400)
return
}
a.redirect(rw, r)
}
func (a *Application) redeemCallback(u *url.URL, c context.Context) (*Claims, error) {
code := u.Query().Get("code")
if code == "" {
return nil, fmt.Errorf("blank code")