implement oidc singl sign on cookie refresher
This commit is contained in:
parent
fe7fb31f05
commit
ac2d04686f
|
|
@ -41,3 +41,5 @@ _testmain.go
|
|||
# vi Dockerfile.dev
|
||||
# docker build -f Dockerfile.dev .
|
||||
Dockerfile.dev
|
||||
|
||||
obj
|
||||
|
|
@ -393,6 +393,9 @@ func buildSessionChain(opts *options.Options, provider providers.Provider, sessi
|
|||
ValidateSession: provider.ValidateSession,
|
||||
}))
|
||||
|
||||
x := opts.Providers[0]
|
||||
chain = chain.Append(middleware.NewCookieRefresh(&middleware.CookieRefreshOptions{IssuerURL: x.OIDCConfig.IssuerURL}))
|
||||
|
||||
return chain
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -31,8 +31,9 @@ type SessionState struct {
|
|||
IntrospectClaims string `msgpack:"ic,omitempty"`
|
||||
|
||||
// Internal helpers, not serialized
|
||||
Clock clock.Clock `msgpack:"-"`
|
||||
Lock Lock `msgpack:"-"`
|
||||
Clock clock.Clock `msgpack:"-"`
|
||||
Lock Lock `msgpack:"-"`
|
||||
SessionJustRefreshed bool `msgpack:"-"`
|
||||
}
|
||||
|
||||
func (s *SessionState) ObtainLock(ctx context.Context, expiration time.Duration) error {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,60 @@
|
|||
package middleware
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/justinas/alice"
|
||||
middlewareapi "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/middleware"
|
||||
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/logger"
|
||||
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/requests"
|
||||
)
|
||||
|
||||
type CookieRefreshOptions struct {
|
||||
IssuerURL string
|
||||
}
|
||||
|
||||
func NewCookieRefresh(opts *CookieRefreshOptions) alice.Constructor {
|
||||
cr := &cookieRefresh{
|
||||
HttpClient: &http.Client{},
|
||||
IssuerURL: opts.IssuerURL,
|
||||
}
|
||||
return cr.refreshCookie
|
||||
}
|
||||
|
||||
type cookieRefresh struct {
|
||||
HttpClient *http.Client
|
||||
IssuerURL string
|
||||
}
|
||||
|
||||
func (cr *cookieRefresh) refreshCookie(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
scope := middlewareapi.GetRequestScope(req)
|
||||
if scope.Session == nil || !scope.Session.SessionJustRefreshed {
|
||||
next.ServeHTTP(rw, req)
|
||||
return
|
||||
}
|
||||
|
||||
cookie, err := req.Cookie("hsdpamcookie")
|
||||
if err != nil {
|
||||
logger.Errorf("SSO Cookie Refresher - Could find 'hsdpamcookie' cookie in the request: %v", err)
|
||||
return
|
||||
}
|
||||
resp := requests.New(fmt.Sprintf("%s/session/refresh", cr.IssuerURL)).
|
||||
WithContext(req.Context()).
|
||||
WithMethod("GET").
|
||||
SetHeader("api-version", "1").
|
||||
SetHeader("Cookie", fmt.Sprintf("hsdpamcookie=%s", cookie.Value)).
|
||||
Do()
|
||||
|
||||
if resp.StatusCode() != http.StatusNoContent {
|
||||
bodyString := string(resp.Body())
|
||||
logger.Errorf("SSO Cookie Refresher - Could not refresh the 'hsdpamcookie' cookie due to status and content: %v - %v", resp.StatusCode(), bodyString)
|
||||
return
|
||||
} else {
|
||||
logger.Print("SSO Cookie Refresher - Cookie 'hsdpamcookie' refreshed")
|
||||
}
|
||||
|
||||
next.ServeHTTP(rw, req)
|
||||
})
|
||||
}
|
||||
|
|
@ -48,6 +48,9 @@ type StoredSessionLoaderOptions struct {
|
|||
// If the sesssion is older than `RefreshPeriod` but the provider doesn't
|
||||
// refresh it, we must re-validate using this validation.
|
||||
ValidateSession func(context.Context, *sessionsapi.SessionState) bool
|
||||
|
||||
// Callback that is called when a session is refreshed
|
||||
OnSessionRefreshed *func(context.Context, *http.Request, *sessionsapi.SessionState)
|
||||
}
|
||||
|
||||
// NewStoredSessionLoader creates a new storedSessionLoader which loads
|
||||
|
|
|
|||
|
|
@ -159,6 +159,7 @@ func (p *OIDCProvider) RefreshSession(ctx context.Context, s *sessions.SessionSt
|
|||
if err != nil {
|
||||
return false, fmt.Errorf("unable to redeem refresh token: %v", err)
|
||||
}
|
||||
s.SessionJustRefreshed = true
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue