Add SameSite=None support and conditionally omit SameSite=None for backwards compatibility

This commit is contained in:
Brian Kopp 2020-01-22 13:19:16 -07:00 committed by briankopp
parent 5d05e19cc3
commit 1b523390bb
11 changed files with 249 additions and 6 deletions

View file

@ -46,6 +46,12 @@ const (
// This is used to control the cookie path when use-regex is set to true
annotationAffinityCookiePath = "session-cookie-path"
// This is used to control the SameSite attribute of the cookie
annotationAffinityCookieSameSite = "session-cookie-samesite"
// This is used to control whether SameSite=None should be conditionally applied based on the User-Agent
annotationAffinityCookieConditionalSameSiteNone = "session-cookie-conditional-samesite-none"
// This is used to control the cookie change after request failure
annotationAffinityCookieChangeOnFailure = "session-cookie-change-on-failure"
)
@ -75,6 +81,10 @@ type Cookie struct {
Path string `json:"path"`
// Flag that allows cookie regeneration on request failure
ChangeOnFailure bool `json:"changeonfailure"`
// SameSite attribute value
SameSite string `json:"samesite"`
// Flag that conditionally applies SameSite=None attribute on cookie if user agent accepts it.
ConditionalSameSiteNone bool `json:"conditional-samesite-none"`
}
// cookieAffinityParse gets the annotation values related to Cookie Affinity
@ -107,6 +117,16 @@ func (a affinity) cookieAffinityParse(ing *networking.Ingress) *Cookie {
klog.V(3).Infof("Invalid or no annotation value found in Ingress %v: %v. Ignoring it", ing.Name, annotationAffinityCookieMaxAge)
}
cookie.SameSite, err = parser.GetStringAnnotation(annotationAffinityCookieSameSite, ing)
if err != nil {
klog.V(3).Infof("Invalid or no annotation value found in Ingress %v: %v. Ignoring it", ing.Name, annotationAffinityCookieSameSite)
}
cookie.ConditionalSameSiteNone, err = parser.GetBoolAnnotation(annotationAffinityCookieConditionalSameSiteNone, ing)
if err != nil {
klog.V(3).Infof("Invalid or no annotation value found in Ingress %v: %v. Ignoring it", ing.Name, annotationAffinityCookieConditionalSameSiteNone)
}
cookie.ChangeOnFailure, err = parser.GetBoolAnnotation(annotationAffinityCookieChangeOnFailure, ing)
if err != nil {
klog.V(3).Infof("Invalid or no annotation value found in Ingress %v: %v. Ignoring it", ing.Name, annotationAffinityCookieChangeOnFailure)

View file

@ -592,6 +592,8 @@ func (n *NGINXController) getBackendServers(ingresses []*ingress.Ingress) ([]*in
ups.SessionAffinity.CookieSessionAffinity.Expires = anns.SessionAffinity.Cookie.Expires
ups.SessionAffinity.CookieSessionAffinity.MaxAge = anns.SessionAffinity.Cookie.MaxAge
ups.SessionAffinity.CookieSessionAffinity.Path = cookiePath
ups.SessionAffinity.CookieSessionAffinity.SameSite = anns.SessionAffinity.Cookie.SameSite
ups.SessionAffinity.CookieSessionAffinity.ConditionalSameSiteNone = anns.SessionAffinity.Cookie.ConditionalSameSiteNone
ups.SessionAffinity.CookieSessionAffinity.ChangeOnFailure = anns.SessionAffinity.Cookie.ChangeOnFailure
locs := ups.SessionAffinity.CookieSessionAffinity.Locations

View file

@ -144,12 +144,14 @@ type SessionAffinityConfig struct {
// CookieSessionAffinity defines the structure used in Affinity configured by Cookies.
// +k8s:deepcopy-gen=true
type CookieSessionAffinity struct {
Name string `json:"name"`
Expires string `json:"expires,omitempty"`
MaxAge string `json:"maxage,omitempty"`
Locations map[string][]string `json:"locations,omitempty"`
Path string `json:"path,omitempty"`
ChangeOnFailure bool `json:"change_on_failure,omitempty"`
Name string `json:"name"`
Expires string `json:"expires,omitempty"`
MaxAge string `json:"maxage,omitempty"`
Locations map[string][]string `json:"locations,omitempty"`
Path string `json:"path,omitempty"`
SameSite string `json:"samesite,omitempty"`
ConditionalSameSiteNone bool `json:"conditional_samesite_none,omitempty"`
ChangeOnFailure bool `json:"change_on_failure,omitempty"`
}
// UpstreamHashByConfig described setting from the upstream-hash-by* annotations.

View file

@ -179,6 +179,12 @@ func (csa1 *CookieSessionAffinity) Equal(csa2 *CookieSessionAffinity) bool {
if csa1.MaxAge != csa2.MaxAge {
return false
}
if csa1.SameSite != csa2.SameSite {
return false
}
if csa1.ConditionalSameSiteNone != csa2.ConditionalSameSiteNone {
return false
}
return true
}