git.iko.soy/typeable/oauth2-proxy
on master help sign in
Initialise SessionStore in Options
fbee5eaJoel Speed
oauthproxy.go+9−7
@@ -16,7 +16,7 @@ import (
16 "github.com/mbland/hmacauth"
16 "github.com/mbland/hmacauth"
17 "github.com/pusher/oauth2_proxy/cookie"
17 "github.com/pusher/oauth2_proxy/cookie"
18 "github.com/pusher/oauth2_proxy/logger"
18 "github.com/pusher/oauth2_proxy/logger"
19− "github.com/pusher/oauth2_proxy/pkg/apis/sessions"
19+ sessionsapi "github.com/pusher/oauth2_proxy/pkg/apis/sessions"
20 "github.com/pusher/oauth2_proxy/providers"
20 "github.com/pusher/oauth2_proxy/providers"
21 "github.com/yhat/wsutil"
21 "github.com/yhat/wsutil"
22)
22)
@@ -75,6 +75,7 @@ type OAuthProxy struct {
75 redirectURL *url.URL // the url to receive requests at
75 redirectURL *url.URL // the url to receive requests at
76 whitelistDomains []string
76 whitelistDomains []string
77 provider providers.Provider
77 provider providers.Provider
78+ sessionStore sessionsapi.SessionStore
78 ProxyPrefix string
79 ProxyPrefix string
79 SignInMessage string
80 SignInMessage string
80 HtpasswdFile *HtpasswdFile
81 HtpasswdFile *HtpasswdFile
@@ -249,6 +250,7 @@ func NewOAuthProxy(opts *Options, validator func(string) bool) *OAuthProxy {
249
250
250 ProxyPrefix: opts.ProxyPrefix,
251 ProxyPrefix: opts.ProxyPrefix,
251 provider: opts.provider,
252 provider: opts.provider,
253+ sessionStore: opts.sessionStore,
252 serveMux: serveMux,
254 serveMux: serveMux,
253 redirectURL: redirectURL,
255 redirectURL: redirectURL,
254 whitelistDomains: opts.WhitelistDomains,
256 whitelistDomains: opts.WhitelistDomains,
@@ -293,7 +295,7 @@ func (p *OAuthProxy) displayCustomLoginForm() bool {
293 return p.HtpasswdFile != nil && p.DisplayHtpasswdForm
295 return p.HtpasswdFile != nil && p.DisplayHtpasswdForm
294}
296}
295
297
296−func (p *OAuthProxy) redeemCode(host, code string) (s *sessions.SessionState, err error) {
298+func (p *OAuthProxy) redeemCode(host, code string) (s *sessionsapi.SessionState, err error) {
297 if code == "" {
299 if code == "" {
298 return nil, errors.New("missing code")
300 return nil, errors.New("missing code")
299 }
301 }
@@ -485,7 +487,7 @@ func (p *OAuthProxy) SetSessionCookie(rw http.ResponseWriter, req *http.Request,
485}
487}
486
488
487// LoadCookiedSession reads the user's authentication details from the request
489// LoadCookiedSession reads the user's authentication details from the request
488−func (p *OAuthProxy) LoadCookiedSession(req *http.Request) (*sessions.SessionState, time.Duration, error) {
490+func (p *OAuthProxy) LoadCookiedSession(req *http.Request) (*sessionsapi.SessionState, time.Duration, error) {
489 var age time.Duration
491 var age time.Duration
490 c, err := loadCookie(req, p.CookieName)
492 c, err := loadCookie(req, p.CookieName)
491 if err != nil {
493 if err != nil {
@@ -507,7 +509,7 @@ func (p *OAuthProxy) LoadCookiedSession(req *http.Request) (*sessions.SessionSta
507}
509}
508
510
509// SaveSession creates a new session cookie value and sets this on the response
511// SaveSession creates a new session cookie value and sets this on the response
510−func (p *OAuthProxy) SaveSession(rw http.ResponseWriter, req *http.Request, s *sessions.SessionState) error {
512+func (p *OAuthProxy) SaveSession(rw http.ResponseWriter, req *http.Request, s *sessionsapi.SessionState) error {
511 value, err := p.provider.CookieForSession(s, p.CookieCipher)
513 value, err := p.provider.CookieForSession(s, p.CookieCipher)
512 if err != nil {
514 if err != nil {
513 return err
515 return err
@@ -694,7 +696,7 @@ func (p *OAuthProxy) SignIn(rw http.ResponseWriter, req *http.Request) {
694
696
695 user, ok := p.ManualSignIn(rw, req)
697 user, ok := p.ManualSignIn(rw, req)
696 if ok {
698 if ok {
697− session := &sessions.SessionState{User: user}
699+ session := &sessionsapi.SessionState{User: user}
698 p.SaveSession(rw, req, session)
700 p.SaveSession(rw, req, session)
699 http.Redirect(rw, req, redirect, 302)
701 http.Redirect(rw, req, redirect, 302)
700 } else {
702 } else {
@@ -945,7 +947,7 @@ func (p *OAuthProxy) Authenticate(rw http.ResponseWriter, req *http.Request) int
945
947
946// CheckBasicAuth checks the requests Authorization header for basic auth
948// CheckBasicAuth checks the requests Authorization header for basic auth
947// credentials and authenticates these against the proxies HtpasswdFile
949// credentials and authenticates these against the proxies HtpasswdFile
948−func (p *OAuthProxy) CheckBasicAuth(req *http.Request) (*sessions.SessionState, error) {
950+func (p *OAuthProxy) CheckBasicAuth(req *http.Request) (*sessionsapi.SessionState, error) {
949 if p.HtpasswdFile == nil {
951 if p.HtpasswdFile == nil {
950 return nil, nil
952 return nil, nil
951 }
953 }
@@ -967,7 +969,7 @@ func (p *OAuthProxy) CheckBasicAuth(req *http.Request) (*sessions.SessionState,
967 }
969 }
968 if p.HtpasswdFile.Validate(pair[0], pair[1]) {
970 if p.HtpasswdFile.Validate(pair[0], pair[1]) {
969 logger.PrintAuthf(pair[0], req, logger.AuthSuccess, "Authenticated via basic auth and HTpasswd File")
971 logger.PrintAuthf(pair[0], req, logger.AuthSuccess, "Authenticated via basic auth and HTpasswd File")
970− return &sessions.SessionState{User: pair[0]}, nil
972+ return &sessionsapi.SessionState{User: pair[0]}, nil
971 }
973 }
972 logger.PrintAuthf(pair[0], req, logger.AuthFailure, "Invalid authentication via basic auth: not in Htpasswd File")
974 logger.PrintAuthf(pair[0], req, logger.AuthFailure, "Invalid authentication via basic auth: not in Htpasswd File")
973 return nil, nil
975 return nil, nil
options.go+16
@@ -19,6 +19,8 @@ import (
19 "github.com/mbland/hmacauth"
19 "github.com/mbland/hmacauth"
20 "github.com/pusher/oauth2_proxy/logger"
20 "github.com/pusher/oauth2_proxy/logger"
21 "github.com/pusher/oauth2_proxy/pkg/apis/options"
21 "github.com/pusher/oauth2_proxy/pkg/apis/options"
22+ sessionsapi "github.com/pusher/oauth2_proxy/pkg/apis/sessions"
23+ "github.com/pusher/oauth2_proxy/pkg/sessions"
22 "github.com/pusher/oauth2_proxy/providers"
24 "github.com/pusher/oauth2_proxy/providers"
23 "gopkg.in/natefinch/lumberjack.v2"
25 "gopkg.in/natefinch/lumberjack.v2"
24)
26)
@@ -111,6 +113,7 @@ type Options struct {
111 proxyURLs []*url.URL
113 proxyURLs []*url.URL
112 CompiledRegex []*regexp.Regexp
114 CompiledRegex []*regexp.Regexp
113 provider providers.Provider
115 provider providers.Provider
116+ sessionStore sessionsapi.SessionStore
114 signatureData *SignatureData
117 signatureData *SignatureData
115 oidcVerifier *oidc.IDTokenVerifier
118 oidcVerifier *oidc.IDTokenVerifier
116}
119}
@@ -136,6 +139,9 @@ func NewOptions() *Options {
136 CookieExpire: time.Duration(168) * time.Hour,
139 CookieExpire: time.Duration(168) * time.Hour,
137 CookieRefresh: time.Duration(0),
140 CookieRefresh: time.Duration(0),
138 },
141 },
142+ SessionOptions: options.SessionOptions{
143+ Type: "cookie",
144+ },
139 SetXAuthRequest: false,
145 SetXAuthRequest: false,
140 SkipAuthPreflight: false,
146 SkipAuthPreflight: false,
141 PassBasicAuth: true,
147 PassBasicAuth: true,
@@ -283,9 +289,19 @@ func (o *Options) Validate() error {
283 "pass_access_token == true or "+
289 "pass_access_token == true or "+
284 "cookie_refresh != 0, but is %d bytes.%s",
290 "cookie_refresh != 0, but is %d bytes.%s",
285 len(secretBytes(o.CookieSecret)), suffix))
291 len(secretBytes(o.CookieSecret)), suffix))
292+ } else {
293+ // Enable encryption in the session store
294+ o.EnableCipher = true
286 }
295 }
287 }
296 }
288
297
298+ sessionStore, err := sessions.NewSessionStore(&o.SessionOptions, &o.CookieOptions)
299+ if err != nil {
300+ msgs = append(msgs, fmt.Sprintf("error initialising session storage: %v", err))
301+ } else {
302+ o.sessionStore = sessionStore
303+ }
304+
289 if o.CookieRefresh >= o.CookieExpire {
305 if o.CookieRefresh >= o.CookieExpire {
290 msgs = append(msgs, fmt.Sprintf(
306 msgs = append(msgs, fmt.Sprintf(
291 "cookie_refresh (%s) must be less than "+
307 "cookie_refresh (%s) must be less than "+
pkg/apis/options/sessions.go+5−2
@@ -2,7 +2,8 @@ package options
2
2
3// SessionOptions contains configuration options for the SessionStore providers.
3// SessionOptions contains configuration options for the SessionStore providers.
4type SessionOptions struct {
4type SessionOptions struct {
5− Type string `flag:"session-store-type" cfg:"session_store_type" env:"OAUTH2_PROXY_SESSION_STORE_TYPE"`
5+ Type string `flag:"session-store-type" cfg:"session_store_type" env:"OAUTH2_PROXY_SESSION_STORE_TYPE"`
6+ EnableCipher bool // Allow the user to choose encryption or not
6 CookieStoreOptions
7 CookieStoreOptions
7}
8}
8
9
@@ -11,4 +12,6 @@ type SessionOptions struct {
11var CookieSessionStoreType = "cookie"
12var CookieSessionStoreType = "cookie"
12
13
13// CookieStoreOptions contains configuration options for the CookieSessionStore.
14// CookieStoreOptions contains configuration options for the CookieSessionStore.
14−type CookieStoreOptions struct{}
15+type CookieStoreOptions struct {
16+ EnableCipher bool // Allow the user to choose encryption or not
17+}
pkg/sessions/cookie/session_store.go+1−1
@@ -126,7 +126,7 @@ func (s *SessionStore) makeCookie(req *http.Request, name string, value string,
126// the configuration given
126// the configuration given
127func NewCookieSessionStore(opts options.CookieStoreOptions, cookieOpts *options.CookieOptions) (sessions.SessionStore, error) {
127func NewCookieSessionStore(opts options.CookieStoreOptions, cookieOpts *options.CookieOptions) (sessions.SessionStore, error) {
128 var cipher *cookie.Cipher
128 var cipher *cookie.Cipher
129− if len(cookieOpts.CookieSecret) > 0 {
129+ if opts.EnableCipher {
130 var err error
130 var err error
131 cipher, err = cookie.NewCipher(utils.SecretBytes(cookieOpts.CookieSecret))
131 cipher, err = cookie.NewCipher(utils.SecretBytes(cookieOpts.CookieSecret))
132 if err != nil {
132 if err != nil {
pkg/sessions/session_store.go+2
@@ -12,6 +12,8 @@ import (
12func NewSessionStore(opts *options.SessionOptions, cookieOpts *options.CookieOptions) (sessions.SessionStore, error) {
12func NewSessionStore(opts *options.SessionOptions, cookieOpts *options.CookieOptions) (sessions.SessionStore, error) {
13 switch opts.Type {
13 switch opts.Type {
14 case options.CookieSessionStoreType:
14 case options.CookieSessionStoreType:
15+ // Ensure EnableCipher is propogated from the parent option
16+ opts.CookieStoreOptions.EnableCipher = opts.EnableCipher
15 return cookie.NewCookieSessionStore(opts.CookieStoreOptions, cookieOpts)
17 return cookie.NewCookieSessionStore(opts.CookieStoreOptions, cookieOpts)
16 default:
18 default:
17 return nil, fmt.Errorf("unknown session store type '%s'", opts.Type)
19 return nil, fmt.Errorf("unknown session store type '%s'", opts.Type)
pkg/sessions/session_store_test.go+15−1
@@ -181,12 +181,13 @@ var _ = Describe("NewSessionStore", func() {
181 SessionStoreInterfaceTests()
181 SessionStoreInterfaceTests()
182 })
182 })
183
183
184− Context("with a cookie-secret set", func() {
184+ Context("with encryption enabled", func() {
185 BeforeEach(func() {
185 BeforeEach(func() {
186 secret := make([]byte, 32)
186 secret := make([]byte, 32)
187 _, err := rand.Read(secret)
187 _, err := rand.Read(secret)
188 Expect(err).ToNot(HaveOccurred())
188 Expect(err).ToNot(HaveOccurred())
189 cookieOpts.CookieSecret = base64.URLEncoding.EncodeToString(secret)
189 cookieOpts.CookieSecret = base64.URLEncoding.EncodeToString(secret)
190+ opts.EnableCipher = true
190
191
191 ss, err = sessions.NewSessionStore(opts, cookieOpts)
192 ss, err = sessions.NewSessionStore(opts, cookieOpts)
192 Expect(err).ToNot(HaveOccurred())
193 Expect(err).ToNot(HaveOccurred())
@@ -194,6 +195,19 @@ var _ = Describe("NewSessionStore", func() {
194
195
195 SessionStoreInterfaceTests()
196 SessionStoreInterfaceTests()
196 })
197 })
198+
199+ Context("with encryption enabled, but no secret", func() {
200+ BeforeEach(func() {
201+ opts.EnableCipher = true
202+ })
203+
204+ It("returns an error", func() {
205+ ss, err := sessions.NewSessionStore(opts, cookieOpts)
206+ Expect(err).To(HaveOccurred())
207+ Expect(err.Error()).To(Equal("unable to create cipher: crypto/aes: invalid key size 0"))
208+ Expect(ss).To(BeNil())
209+ })
210+ })
197 }
211 }
198
212
199 BeforeEach(func() {
213 BeforeEach(func() {