mirror of
https://github.com/pomerium/pomerium.git
synced 2025-05-10 15:47:36 +02:00
internal/sessions: allow manual session scope
This commit is contained in:
parent
79f96eab52
commit
437dee0315
4 changed files with 37 additions and 31 deletions
|
@ -18,6 +18,7 @@
|
||||||
- Fixed Azure group lookups [GH-190]
|
- Fixed Azure group lookups [GH-190]
|
||||||
- If a session is too large (over 4096 bytes) Pomerium will no longer fail silently. [GH-211]
|
- If a session is too large (over 4096 bytes) Pomerium will no longer fail silently. [GH-211]
|
||||||
- Internal URLs like dashboard now start auth process to login a user if no session is found [GH-205].
|
- Internal URLs like dashboard now start auth process to login a user if no session is found [GH-205].
|
||||||
|
- When set,`CookieDomain` lets a user set the scope of the user session. CSRF cookies will still always be scoped at the individual route level. [GH-181]
|
||||||
|
|
||||||
## v0.0.5
|
## v0.0.5
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,7 @@ func New(opts config.Options) (*Authenticate, error) {
|
||||||
cookieStore, err := sessions.NewCookieStore(
|
cookieStore, err := sessions.NewCookieStore(
|
||||||
&sessions.CookieStoreOptions{
|
&sessions.CookieStoreOptions{
|
||||||
Name: opts.CookieName,
|
Name: opts.CookieName,
|
||||||
|
CookieDomain: opts.CookieDomain,
|
||||||
CookieSecure: opts.CookieSecure,
|
CookieSecure: opts.CookieSecure,
|
||||||
CookieHTTPOnly: opts.CookieHTTPOnly,
|
CookieHTTPOnly: opts.CookieHTTPOnly,
|
||||||
CookieExpire: opts.CookieExpire,
|
CookieExpire: opts.CookieExpire,
|
||||||
|
|
|
@ -68,20 +68,19 @@ func NewCookieStore(opts *CookieStoreOptions) (*CookieStore, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *CookieStore) makeCookie(req *http.Request, name string, value string, expiration time.Duration, now time.Time) *http.Cookie {
|
func (s *CookieStore) makeCookie(req *http.Request, name string, value string, expiration time.Duration, now time.Time) *http.Cookie {
|
||||||
// if csrf, scope cookie to the route or service specific domain
|
|
||||||
domain := req.Host
|
domain := req.Host
|
||||||
if h, _, err := net.SplitHostPort(domain); err == nil {
|
|
||||||
domain = h
|
|
||||||
}
|
|
||||||
if s.CookieDomain != "" {
|
|
||||||
domain = s.CookieDomain
|
|
||||||
}
|
|
||||||
|
|
||||||
// Non-CSRF sessions can shared, and set domain-wide
|
if name == s.csrfName() {
|
||||||
if !strings.Contains(name, "csrf") {
|
domain = req.Host
|
||||||
|
} else if s.CookieDomain != "" {
|
||||||
|
domain = s.CookieDomain
|
||||||
|
} else {
|
||||||
domain = splitDomain(domain)
|
domain = splitDomain(domain)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if h, _, err := net.SplitHostPort(domain); err == nil {
|
||||||
|
domain = h
|
||||||
|
}
|
||||||
c := &http.Cookie{
|
c := &http.Cookie{
|
||||||
Name: name,
|
Name: name,
|
||||||
Value: value,
|
Value: value,
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/go-cmp/cmp"
|
||||||
"github.com/pomerium/pomerium/internal/cryptutil"
|
"github.com/pomerium/pomerium/internal/cryptutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -110,35 +111,39 @@ func TestCookieStore_makeCookie(t *testing.T) {
|
||||||
name string
|
name string
|
||||||
domain string
|
domain string
|
||||||
|
|
||||||
cookieName string
|
cookieDomain string
|
||||||
value string
|
cookieName string
|
||||||
expiration time.Duration
|
value string
|
||||||
want *http.Cookie
|
expiration time.Duration
|
||||||
wantCSRF *http.Cookie
|
want *http.Cookie
|
||||||
|
wantCSRF *http.Cookie
|
||||||
}{
|
}{
|
||||||
{"good", "http://httpbin.corp.pomerium.io", "_pomerium", "value", 0, &http.Cookie{Name: "_pomerium", Value: "value", Path: "/", Domain: "corp.pomerium.io", Secure: true, HttpOnly: true}, &http.Cookie{Name: "_pomerium_csrf", Value: "value", Path: "/", Domain: "httpbin.corp.pomerium.io", Secure: true, HttpOnly: true}},
|
{"good", "http://httpbin.corp.pomerium.io", "", "_pomerium", "value", 0, &http.Cookie{Name: "_pomerium", Value: "value", Path: "/", Domain: "corp.pomerium.io", Secure: true, HttpOnly: true}, &http.Cookie{Name: "_pomerium_csrf", Value: "value", Path: "/", Domain: "httpbin.corp.pomerium.io", Secure: true, HttpOnly: true}},
|
||||||
{"domains with https", "https://httpbin.corp.pomerium.io", "_pomerium", "value", 0, &http.Cookie{Name: "_pomerium", Value: "value", Path: "/", Domain: "corp.pomerium.io", Secure: true, HttpOnly: true}, &http.Cookie{Name: "_pomerium_csrf", Value: "value", Path: "/", Domain: "httpbin.corp.pomerium.io", Secure: true, HttpOnly: true}},
|
{"domains with https", "https://httpbin.corp.pomerium.io", "", "_pomerium", "value", 0, &http.Cookie{Name: "_pomerium", Value: "value", Path: "/", Domain: "corp.pomerium.io", Secure: true, HttpOnly: true}, &http.Cookie{Name: "_pomerium_csrf", Value: "value", Path: "/", Domain: "httpbin.corp.pomerium.io", Secure: true, HttpOnly: true}},
|
||||||
{"domain with port", "http://httpbin.corp.pomerium.io:443", "_pomerium", "value", 0, &http.Cookie{Name: "_pomerium", Value: "value", Path: "/", Domain: "corp.pomerium.io", Secure: true, HttpOnly: true}, &http.Cookie{Name: "_pomerium_csrf", Value: "value", Path: "/", Domain: "httpbin.corp.pomerium.io", Secure: true, HttpOnly: true}},
|
{"domain with port", "http://httpbin.corp.pomerium.io:443", "", "_pomerium", "value", 0, &http.Cookie{Name: "_pomerium", Value: "value", Path: "/", Domain: "corp.pomerium.io", Secure: true, HttpOnly: true}, &http.Cookie{Name: "_pomerium_csrf", Value: "value", Path: "/", Domain: "httpbin.corp.pomerium.io", Secure: true, HttpOnly: true}},
|
||||||
{"expiration set", "http://httpbin.corp.pomerium.io:443", "_pomerium", "value", 10 * time.Second, &http.Cookie{Expires: now.Add(10 * time.Second), Name: "_pomerium", Value: "value", Path: "/", Domain: "corp.pomerium.io", Secure: true, HttpOnly: true}, &http.Cookie{Expires: now.Add(10 * time.Second), Name: "_pomerium_csrf", Value: "value", Path: "/", Domain: "httpbin.corp.pomerium.io", Secure: true, HttpOnly: true}},
|
{"expiration set", "http://httpbin.corp.pomerium.io:443", "", "_pomerium", "value", 10 * time.Second, &http.Cookie{Expires: now.Add(10 * time.Second), Name: "_pomerium", Value: "value", Path: "/", Domain: "corp.pomerium.io", Secure: true, HttpOnly: true}, &http.Cookie{Expires: now.Add(10 * time.Second), Name: "_pomerium_csrf", Value: "value", Path: "/", Domain: "httpbin.corp.pomerium.io", Secure: true, HttpOnly: true}},
|
||||||
|
{"good", "http://httpbin.corp.pomerium.io", "pomerium.io", "_pomerium", "value", 0, &http.Cookie{Name: "_pomerium", Value: "value", Path: "/", Domain: "pomerium.io", Secure: true, HttpOnly: true}, &http.Cookie{Name: "_pomerium_csrf", Value: "value", Path: "/", Domain: "httpbin.corp.pomerium.io", Secure: true, HttpOnly: true}},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
r := httptest.NewRequest("GET", tt.domain, nil)
|
r := httptest.NewRequest("GET", tt.domain, nil)
|
||||||
|
|
||||||
o := &CookieStoreOptions{
|
s, err := NewCookieStore(
|
||||||
Name: "_pomerium",
|
&CookieStoreOptions{
|
||||||
CookieSecure: true,
|
Name: "_pomerium",
|
||||||
CookieHTTPOnly: true,
|
CookieSecure: true,
|
||||||
CookieDomain: "httpbin.corp.pomerium.io",
|
CookieHTTPOnly: true,
|
||||||
CookieExpire: 10 * time.Second,
|
CookieDomain: tt.cookieDomain,
|
||||||
CookieCipher: cipher}
|
CookieExpire: 10 * time.Second,
|
||||||
|
CookieCipher: cipher})
|
||||||
s, _ := NewCookieStore(o)
|
if err != nil {
|
||||||
if got := s.makeCookie(r, tt.cookieName, tt.value, tt.expiration, now); !reflect.DeepEqual(got, tt.want) {
|
t.Fatal(err)
|
||||||
t.Errorf("CookieStore.makeCookie() = \n%#v, \nwant\n%#v", got, tt.want)
|
|
||||||
}
|
}
|
||||||
if got := s.makeSessionCookie(r, tt.value, tt.expiration, now); !reflect.DeepEqual(got, tt.want) {
|
if diff := cmp.Diff(s.makeCookie(r, tt.cookieName, tt.value, tt.expiration, now), tt.want); diff != "" {
|
||||||
t.Errorf("CookieStore.makeCookie() = \n%#v, \nwant\n%#v", got, tt.want)
|
t.Errorf("CookieStore.makeCookie() = \n%s", diff)
|
||||||
|
}
|
||||||
|
if diff := cmp.Diff(s.makeSessionCookie(r, tt.value, tt.expiration, now), tt.want); diff != "" {
|
||||||
|
t.Errorf("CookieStore.makeSessionCookie() = \n%s", diff)
|
||||||
}
|
}
|
||||||
got := s.makeCSRFCookie(r, tt.value, tt.expiration, now)
|
got := s.makeCSRFCookie(r, tt.value, tt.expiration, now)
|
||||||
tt.wantCSRF.Name = "_pomerium_csrf"
|
tt.wantCSRF.Name = "_pomerium_csrf"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue