diff --git a/src/backend/app-core/auth.go b/src/backend/app-core/auth.go index a99001c845..e3430211fe 100644 --- a/src/backend/app-core/auth.go +++ b/src/backend/app-core/auth.go @@ -8,7 +8,6 @@ import ( "fmt" "net/http" "net/url" - "regexp" "strconv" "strings" "time" @@ -48,9 +47,6 @@ const SessionExpiresOnHeader = "X-Cap-Session-Expires-On" // ClientRequestDateHeader Custom header for getting date form client const ClientRequestDateHeader = "X-Cap-Request-Date" -// EmptyCookieMatcher - Used to detect and remove empty Cookies sent by certain browsers -var EmptyCookieMatcher *regexp.Regexp = regexp.MustCompile(portalSessionName + "=(?:;[ ]*|$)") - // XSRFTokenHeader - XSRF Token Header name const XSRFTokenHeader = "X-Xsrf-Token" @@ -68,7 +64,7 @@ func (p *portalProxy) getUAAIdentityEndpoint() string { func (p *portalProxy) removeEmptyCookie(c echo.Context) { req := c.Request().(*standard.Request).Request originalCookie := req.Header.Get("Cookie") - cleanCookie := EmptyCookieMatcher.ReplaceAllLiteralString(originalCookie, "") + cleanCookie := p.EmptyCookieMatcher.ReplaceAllLiteralString(originalCookie, "") req.Header.Set("Cookie", cleanCookie) } diff --git a/src/backend/app-core/main.go b/src/backend/app-core/main.go index 915b4c94d9..bf3de4984b 100644 --- a/src/backend/app-core/main.go +++ b/src/backend/app-core/main.go @@ -1,12 +1,14 @@ package main import ( + "crypto/sha1" "crypto/tls" "database/sql" "encoding/gob" "encoding/hex" "errors" "fmt" + "io" "io/ioutil" "net" "net/http" @@ -14,6 +16,7 @@ import ( "os/signal" "path" "path/filepath" + "regexp" "strings" "syscall" "time" @@ -323,6 +326,8 @@ func initSessionStore(db *sql.DB, databaseProvider string, pc interfaces.PortalC domain = "" } + log.Infof("Session Cookie Domain: %s", domain) + // Store depends on the DB Type if databaseProvider == datastore.PGSQL { log.Info("Creating Postgres session store") @@ -446,11 +451,26 @@ func detectTLSCert(pc interfaces.PortalConfig) (string, string, error) { func newPortalProxy(pc interfaces.PortalConfig, dcp *sql.DB, ss HttpSessionStore, sessionStoreOptions *sessions.Options) *portalProxy { log.Debug("newPortalProxy") + + // Generate cookie name - avoids issues if the cookie domain is changed + cookieName := jetstreamSessionName + domain := pc.CookieDomain + if len(domain) > 0 && domain != "-" { + h := sha1.New() + io.WriteString(h, domain) + hash := fmt.Sprintf("%x", h.Sum(nil)) + cookieName = fmt.Sprintf("%s-%s", jetstreamSessionName, hash[0:10]) + } + + log.Infof("Session Cookie name: %s", cookieName) + pp := &portalProxy{ Config: pc, DatabaseConnectionPool: dcp, SessionStore: ss, SessionStoreOptions: sessionStoreOptions, + SessionCookieName: cookieName, + EmptyCookieMatcher: regexp.MustCompile(cookieName + "=(?:;[ ]*|$)"), } return pp diff --git a/src/backend/app-core/portal_proxy.go b/src/backend/app-core/portal_proxy.go index d62e33b720..523ab4e77b 100644 --- a/src/backend/app-core/portal_proxy.go +++ b/src/backend/app-core/portal_proxy.go @@ -2,6 +2,7 @@ package main import ( "database/sql" + "regexp" "time" "github.com/SUSE/stratos-ui/repository/interfaces" @@ -14,6 +15,8 @@ type portalProxy struct { SessionStore interfaces.SessionStorer SessionStoreOptions *sessions.Options Plugins map[string]interfaces.StratosPlugin + SessionCookieName string + EmptyCookieMatcher *regexp.Regexp // Used to detect and remove empty Cookies sent by certain browsers } // HttpSessionStore - Interface for a store that can manage HTTP Sessions diff --git a/src/backend/app-core/session.go b/src/backend/app-core/session.go index af88262471..ecef06c0ec 100644 --- a/src/backend/app-core/session.go +++ b/src/backend/app-core/session.go @@ -11,7 +11,8 @@ import ( ) const ( - portalSessionName = "console-session" + // Default cookie name/cookie name prefix + jetstreamSessionName = "console-session" ) // SessionValueNotFound - Error returned when a requested key was not found in the session @@ -26,7 +27,7 @@ func (e *SessionValueNotFound) Error() string { func (p *portalProxy) GetSession(c echo.Context) (*sessions.Session, error) { log.Debug("getSession") req := c.Request().(*standard.Request).Request - return p.SessionStore.Get(req, portalSessionName) + return p.SessionStore.Get(req, p.SessionCookieName) } func (p *portalProxy) GetSessionValue(c echo.Context, key string) (interface{}, error) { @@ -80,7 +81,7 @@ func (p *portalProxy) setSessionValues(c echo.Context, values map[string]interfa log.Debug("setSessionValues") req := c.Request().(*standard.Request).Request - session, err := p.SessionStore.Get(req, portalSessionName) + session, err := p.SessionStore.Get(req, p.SessionCookieName) if err != nil { return err } @@ -96,7 +97,7 @@ func (p *portalProxy) unsetSessionValue(c echo.Context, sessionKey string) error log.Debug("unsetSessionValues") req := c.Request().(*standard.Request).Request - session, err := p.SessionStore.Get(req, portalSessionName) + session, err := p.SessionStore.Get(req, p.SessionCookieName) if err != nil { return err } @@ -111,7 +112,7 @@ func (p *portalProxy) clearSession(c echo.Context) error { req := c.Request().(*standard.Request).Request res := c.Response().(*standard.Response).ResponseWriter - session, err := p.SessionStore.Get(req, portalSessionName) + session, err := p.SessionStore.Get(req, p.SessionCookieName) if err != nil { return err }