github.com/crewjam/saml@v0.4.14/samlsp/session_cookie.go (about) 1 package samlsp 2 3 import ( 4 "net" 5 "net/http" 6 "time" 7 8 "github.com/crewjam/saml" 9 ) 10 11 const defaultSessionCookieName = "token" 12 13 var _ SessionProvider = CookieSessionProvider{} 14 15 // CookieSessionProvider is an implementation of SessionProvider that stores 16 // session tokens in an HTTP cookie. 17 type CookieSessionProvider struct { 18 Name string 19 Domain string 20 HTTPOnly bool 21 Secure bool 22 SameSite http.SameSite 23 MaxAge time.Duration 24 Codec SessionCodec 25 } 26 27 // CreateSession is called when we have received a valid SAML assertion and 28 // should create a new session and modify the http response accordingly, e.g. by 29 // setting a cookie. 30 func (c CookieSessionProvider) CreateSession(w http.ResponseWriter, r *http.Request, assertion *saml.Assertion) error { 31 // Cookies should not have the port attached to them so strip it off 32 if domain, _, err := net.SplitHostPort(c.Domain); err == nil { 33 c.Domain = domain 34 } 35 36 session, err := c.Codec.New(assertion) 37 if err != nil { 38 return err 39 } 40 41 value, err := c.Codec.Encode(session) 42 if err != nil { 43 return err 44 } 45 46 http.SetCookie(w, &http.Cookie{ 47 Name: c.Name, 48 Domain: c.Domain, 49 Value: value, 50 MaxAge: int(c.MaxAge.Seconds()), 51 HttpOnly: c.HTTPOnly, 52 Secure: c.Secure || r.URL.Scheme == "https", 53 SameSite: c.SameSite, 54 Path: "/", 55 }) 56 return nil 57 } 58 59 // DeleteSession is called to modify the response such that it removed the current 60 // session, e.g. by deleting a cookie. 61 func (c CookieSessionProvider) DeleteSession(w http.ResponseWriter, r *http.Request) error { 62 // Cookies should not have the port attached to them so strip it off 63 if domain, _, err := net.SplitHostPort(c.Domain); err == nil { 64 c.Domain = domain 65 } 66 67 cookie, err := r.Cookie(c.Name) 68 69 if err == http.ErrNoCookie { 70 return nil 71 } 72 if err != nil { 73 return err 74 } 75 76 cookie.Value = "" 77 cookie.Expires = time.Unix(1, 0) // past time as close to epoch as possible, but not zero time.Time{} 78 cookie.Path = "/" 79 cookie.Domain = c.Domain 80 http.SetCookie(w, cookie) 81 return nil 82 } 83 84 // GetSession returns the current Session associated with the request, or 85 // ErrNoSession if there is no valid session. 86 func (c CookieSessionProvider) GetSession(r *http.Request) (Session, error) { 87 cookie, err := r.Cookie(c.Name) 88 if err == http.ErrNoCookie { 89 return nil, ErrNoSession 90 } else if err != nil { 91 return nil, err 92 } 93 94 session, err := c.Codec.Decode(cookie.Value) 95 if err != nil { 96 return nil, ErrNoSession 97 } 98 return session, nil 99 }