git.iko.soy/typeable/oauth2-proxy
on master help sign in
Add support for setting groups on session when using basic auth (#1064)

* Add support for setting groups on session when using basic auth * Refactoring based on feedback * Attribution

commit220b3708fc4e1de5e30135b48c8d8a2ef7efd518 authorStefan Sedich <stefan.sedich@gmail.com> dateThu 25 Feb 2021, 13:02 (6 years ago) parentd3147c3
6 files changed+20−8
CHANGELOG.md+1 docs/docs/configuration/overview.md+1 oauthproxy.go+1−1 pkg/apis/options/options.go+2 pkg/middleware/basic_session.go+7−6 pkg/middleware/basic_session_test.go+8−1
CHANGELOG.md+1
@@ -8,6 +8,7 @@
88
99## Changes since v7.0.1
1010
11+- [#1064](https://github.com/oauth2-proxy/oauth2-proxy/pull/1064) Add support for setting groups on session when using basic auth (@stefansedich)
1112- [#1056](https://github.com/oauth2-proxy/oauth2-proxy/pull/1056) Add option for custom logos on the sign in page (@JoelSpeed)
1213- [#1054](https://github.com/oauth2-proxy/oauth2-proxy/pull/1054) Update to Go 1.16 (@JoelSpeed)
1314- [#1052](https://github.com/oauth2-proxy/oauth2-proxy/pull/1052) Update golangci-lint to latest version (v1.36.0) (@JoelSpeed)
docs/docs/configuration/overview.md+1
@@ -62,6 +62,7 @@ An example [oauth2-proxy.cfg](https://github.com/oauth2-proxy/oauth2-proxy/blob/
6262| `--google-group` | string | restrict logins to members of this google group (may be given multiple times). | |
6363| `--google-service-account-json` | string | the path to the service account json credentials | |
6464| `--htpasswd-file` | string | additionally authenticate against a htpasswd file. Entries must be created with `htpasswd -B` for bcrypt encryption | |
65+| `--htpasswd-user-group` | string \| list | the groups to be set on sessions for htpasswd users | |
6566| `--http-address` | string | `[http://]<addr>:<port>` or `unix://<path>` to listen on for HTTP clients | `"127.0.0.1:4180"` |
6667| `--https-address` | string | `<addr>:<port>` to listen on for HTTPS clients | `":443"` |
6768| `--logging-compress` | bool | Should rotated log files be compressed using gzip | false |
oauthproxy.go+1−1
@@ -277,7 +277,7 @@ func buildSessionChain(opts *options.Options, sessionStore sessionsapi.SessionSt
277277 }
278278
279279 if validator != nil {
280− chain = chain.Append(middleware.NewBasicAuthSessionLoader(validator))
280+ chain = chain.Append(middleware.NewBasicAuthSessionLoader(validator, opts.HtpasswdUserGroups))
281281 }
282282
283283 chain = chain.Append(middleware.NewStoredSessionLoader(&middleware.StoredSessionLoaderOptions{
pkg/apis/options/options.go+2
@@ -54,6 +54,7 @@ type Options struct {
5454 GoogleAdminEmail string `flag:"google-admin-email" cfg:"google_admin_email"`
5555 GoogleServiceAccountJSON string `flag:"google-service-account-json" cfg:"google_service_account_json"`
5656 HtpasswdFile string `flag:"htpasswd-file" cfg:"htpasswd_file"`
57+ HtpasswdUserGroups []string `flag:"htpasswd-user-group" cfg:"htpasswd_user_groups"`
5758
5859 Cookie Cookie `cfg:",squash"`
5960 Session SessionOptions `cfg:",squash"`
@@ -199,6 +200,7 @@ func NewFlagSet() *pflag.FlagSet {
199200 flagSet.String("client-secret-file", "", "the file with OAuth Client Secret")
200201 flagSet.String("authenticated-emails-file", "", "authenticate against emails via file (one per line)")
201202 flagSet.String("htpasswd-file", "", "additionally authenticate against a htpasswd file. Entries must be created with \"htpasswd -B\" for bcrypt encryption")
203+ flagSet.StringSlice("htpasswd-user-group", []string{}, "the groups to be set on sessions for htpasswd users (may be given multiple times)")
202204 flagSet.String("proxy-prefix", "/oauth2", "the url root path that this proxy should be nested under (e.g. /<oauth2>/sign_in)")
203205 flagSet.String("ping-path", "/ping", "the ping endpoint that can be used for basic health checks")
204206 flagSet.String("ping-user-agent", "", "special User-Agent that will be used for basic health checks")
pkg/middleware/basic_session.go+7−6
@@ -11,9 +11,9 @@ import (
1111 "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/logger"
1212)
1313
14−func NewBasicAuthSessionLoader(validator basic.Validator) alice.Constructor {
14+func NewBasicAuthSessionLoader(validator basic.Validator, sessionGroups []string) alice.Constructor {
1515 return func(next http.Handler) http.Handler {
16− return loadBasicAuthSession(validator, next)
16+ return loadBasicAuthSession(validator, sessionGroups, next)
1717 }
1818}
1919
@@ -22,7 +22,7 @@ func NewBasicAuthSessionLoader(validator basic.Validator) alice.Constructor {
2222// If no authorization header is found, or the header is invalid, no session
2323// will be loaded and the request will be passed to the next handler.
2424// If a session was loaded by a previous handler, it will not be replaced.
25−func loadBasicAuthSession(validator basic.Validator, next http.Handler) http.Handler {
25+func loadBasicAuthSession(validator basic.Validator, sessionGroups []string, next http.Handler) http.Handler {
2626 return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
2727 scope := middlewareapi.GetRequestScope(req)
2828 // If scope is nil, this will panic.
@@ -33,7 +33,7 @@ func loadBasicAuthSession(validator basic.Validator, next http.Handler) http.Han
3333 return
3434 }
3535
36− session, err := getBasicSession(validator, req)
36+ session, err := getBasicSession(validator, sessionGroups, req)
3737 if err != nil {
3838 logger.Errorf("Error retrieving session from token in Authorization header: %v", err)
3939 }
@@ -47,7 +47,7 @@ func loadBasicAuthSession(validator basic.Validator, next http.Handler) http.Han
4747// getBasicSession attempts to load a basic session from the request.
4848// If the credentials in the request exist within the htpasswdMap,
4949// a new session will be created.
50−func getBasicSession(validator basic.Validator, req *http.Request) (*sessionsapi.SessionState, error) {
50+func getBasicSession(validator basic.Validator, sessionGroups []string, req *http.Request) (*sessionsapi.SessionState, error) {
5151 auth := req.Header.Get("Authorization")
5252 if auth == "" {
5353 // No auth header provided, so don't attempt to load a session
@@ -61,7 +61,8 @@ func getBasicSession(validator basic.Validator, req *http.Request) (*sessionsapi
6161
6262 if validator.Validate(user, password) {
6363 logger.PrintAuthf(user, req, logger.AuthSuccess, "Authenticated via basic auth and HTpasswd File")
64− return &sessionsapi.SessionState{User: user}, nil
64+
65+ return &sessionsapi.SessionState{User: user, Groups: sessionGroups}, nil
6566 }
6667
6768 logger.PrintAuthf(user, req, logger.AuthFailure, "Invalid authentication via basic auth: not in Htpasswd File")
pkg/middleware/basic_session_test.go+8−1
@@ -26,6 +26,7 @@ var _ = Describe("Basic Auth Session Suite", func() {
2626
2727 type basicAuthSessionLoaderTableInput struct {
2828 authorizationHeader string
29+ sessionGroups []string
2930 existingSession *sessionsapi.SessionState
3031 expectedSession *sessionsapi.SessionState
3132 }
@@ -54,7 +55,7 @@ var _ = Describe("Basic Auth Session Suite", func() {
5455 // Create the handler with a next handler that will capture the session
5556 // from the scope
5657 var gotSession *sessionsapi.SessionState
57− handler := NewBasicAuthSessionLoader(validator)(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
58+ handler := NewBasicAuthSessionLoader(validator, in.sessionGroups)(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
5859 gotSession = middlewareapi.GetRequestScope(r).Session
5960 }))
6061 handler.ServeHTTP(rw, req)
@@ -111,6 +112,12 @@ var _ = Describe("Basic Auth Session Suite", func() {
111112 existingSession: nil,
112113 expectedSession: &sessionsapi.SessionState{User: "admin"},
113114 }),
115+ Entry("Basic with groups", basicAuthSessionLoaderTableInput{
116+ authorizationHeader: "Basic YWRtaW46QWRtMW4xc3RyJHQwcg==",
117+ sessionGroups: []string{"a", "b"},
118+ existingSession: nil,
119+ expectedSession: &sessionsapi.SessionState{User: "admin", Groups: []string{"a", "b"}},
120+ }),
114121 )
115122 })
116123})