mirror of
https://github.com/oauth2-proxy/oauth2-proxy.git
synced 2025-05-31 23:19:50 +02:00
Integrate cookie builder in cookie session store
This commit is contained in:
parent
2dcda8539c
commit
7f1ae0ee4d
@ -1,7 +1,6 @@
|
|||||||
package cookie
|
package cookie
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"regexp"
|
"regexp"
|
||||||
@ -9,7 +8,7 @@ import (
|
|||||||
|
|
||||||
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options"
|
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options"
|
||||||
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/sessions"
|
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/sessions"
|
||||||
pkgcookies "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/cookies"
|
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/cookies"
|
||||||
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/encryption"
|
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/encryption"
|
||||||
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/logger"
|
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/logger"
|
||||||
)
|
)
|
||||||
@ -27,9 +26,9 @@ var _ sessions.SessionStore = &SessionStore{}
|
|||||||
// SessionStore is an implementation of the sessions.SessionStore
|
// SessionStore is an implementation of the sessions.SessionStore
|
||||||
// interface that stores sessions in client side cookies
|
// interface that stores sessions in client side cookies
|
||||||
type SessionStore struct {
|
type SessionStore struct {
|
||||||
Cookie *options.Cookie
|
cookieBuilder cookies.Builder
|
||||||
CookieCipher encryption.Cipher
|
CookieCipher encryption.Cipher
|
||||||
Minimal bool
|
Minimal bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save takes a sessions.SessionState and stores the information from it
|
// Save takes a sessions.SessionState and stores the information from it
|
||||||
@ -48,17 +47,18 @@ func (s *SessionStore) Save(rw http.ResponseWriter, req *http.Request, ss *sessi
|
|||||||
// Load reads sessions.SessionState information from Cookies within the
|
// Load reads sessions.SessionState information from Cookies within the
|
||||||
// HTTP request object
|
// HTTP request object
|
||||||
func (s *SessionStore) Load(req *http.Request) (*sessions.SessionState, error) {
|
func (s *SessionStore) Load(req *http.Request) (*sessions.SessionState, error) {
|
||||||
c, err := loadCookie(req, s.Cookie.Name)
|
c, err := loadCookie(req, s.cookieBuilder.GetName())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// always http.ErrNoCookie
|
// always http.ErrNoCookie
|
||||||
return nil, fmt.Errorf("cookie %q not present", s.Cookie.Name)
|
return nil, fmt.Errorf("cookie %q not present", s.cookieBuilder.GetName())
|
||||||
}
|
|
||||||
val, _, ok := encryption.Validate(c, s.Cookie.Secret, s.Cookie.Expire)
|
|
||||||
if !ok {
|
|
||||||
return nil, errors.New("cookie signature not valid")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
session, err := sessions.DecodeSessionState(val, s.CookieCipher, true)
|
val, err := s.cookieBuilder.ValidateCookie(c)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("cookie signature not valid: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
session, err := sessions.DecodeSessionState([]byte(val), s.CookieCipher, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -69,11 +69,17 @@ func (s *SessionStore) Load(req *http.Request) (*sessions.SessionState, error) {
|
|||||||
// clear the session
|
// clear the session
|
||||||
func (s *SessionStore) Clear(rw http.ResponseWriter, req *http.Request) error {
|
func (s *SessionStore) Clear(rw http.ResponseWriter, req *http.Request) error {
|
||||||
// matches CookieName, CookieName_<number>
|
// matches CookieName, CookieName_<number>
|
||||||
var cookieNameRegex = regexp.MustCompile(fmt.Sprintf("^%s(_\\d+)?$", s.Cookie.Name))
|
var cookieNameRegex = regexp.MustCompile(fmt.Sprintf("^%s(_\\d+)?$", s.cookieBuilder.GetName()))
|
||||||
|
|
||||||
for _, c := range req.Cookies() {
|
for _, c := range req.Cookies() {
|
||||||
if cookieNameRegex.MatchString(c.Name) {
|
if cookieNameRegex.MatchString(c.Name) {
|
||||||
clearCookie := s.makeCookie(req, c.Name, "", time.Hour*-1, time.Now())
|
clearCookie, err := s.cookieBuilder.
|
||||||
|
WithName(c.Name).
|
||||||
|
WithExpiration(time.Hour*-1).
|
||||||
|
MakeCookie(req, "")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
http.SetCookie(rw, clearCookie)
|
http.SetCookie(rw, clearCookie)
|
||||||
}
|
}
|
||||||
@ -111,30 +117,14 @@ func (s *SessionStore) setSessionCookie(rw http.ResponseWriter, req *http.Reques
|
|||||||
// makeSessionCookie creates an http.Cookie containing the authenticated user's
|
// makeSessionCookie creates an http.Cookie containing the authenticated user's
|
||||||
// authentication details
|
// authentication details
|
||||||
func (s *SessionStore) makeSessionCookie(req *http.Request, value []byte, now time.Time) ([]*http.Cookie, error) {
|
func (s *SessionStore) makeSessionCookie(req *http.Request, value []byte, now time.Time) ([]*http.Cookie, error) {
|
||||||
strValue := string(value)
|
cookie, err := s.cookieBuilder.WithSignedValue(true).WithStart(now).MakeCookie(req, string(value))
|
||||||
if strValue != "" {
|
if err != nil {
|
||||||
var err error
|
return nil, fmt.Errorf("could not create cookie: %v", err)
|
||||||
strValue, err = encryption.SignedValue(s.Cookie.Secret, s.Cookie.Name, value, now)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
c := s.makeCookie(req, s.Cookie.Name, strValue, s.Cookie.Expire, now)
|
if len(cookie.String()) > maxCookieLength {
|
||||||
if len(c.String()) > maxCookieLength {
|
return splitCookie(cookie), nil
|
||||||
return splitCookie(c), nil
|
|
||||||
}
|
}
|
||||||
return []*http.Cookie{c}, nil
|
return []*http.Cookie{cookie}, nil
|
||||||
}
|
|
||||||
|
|
||||||
func (s *SessionStore) makeCookie(req *http.Request, name string, value string, expiration time.Duration, now time.Time) *http.Cookie {
|
|
||||||
return pkgcookies.MakeCookieFromOptions(
|
|
||||||
req,
|
|
||||||
name,
|
|
||||||
value,
|
|
||||||
s.Cookie,
|
|
||||||
expiration,
|
|
||||||
now,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCookieSessionStore initialises a new instance of the SessionStore from
|
// NewCookieSessionStore initialises a new instance of the SessionStore from
|
||||||
@ -146,9 +136,9 @@ func NewCookieSessionStore(opts *options.SessionOptions, cookieOpts *options.Coo
|
|||||||
}
|
}
|
||||||
|
|
||||||
return &SessionStore{
|
return &SessionStore{
|
||||||
CookieCipher: cipher,
|
CookieCipher: cipher,
|
||||||
Cookie: cookieOpts,
|
cookieBuilder: cookies.NewBuilder(*cookieOpts),
|
||||||
Minimal: opts.Cookie.Minimal,
|
Minimal: opts.Cookie.Minimal,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user