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
This commit is contained in:
Stefan Sedich
2021-02-25 13:02:23 -08:00
committed by GitHub
parent d3147c3ab2
commit 220b3708fc
6 changed files with 20 additions and 8 deletions
+2
View File
@@ -54,6 +54,7 @@ type Options struct {
GoogleAdminEmail string `flag:"google-admin-email" cfg:"google_admin_email"`
GoogleServiceAccountJSON string `flag:"google-service-account-json" cfg:"google_service_account_json"`
HtpasswdFile string `flag:"htpasswd-file" cfg:"htpasswd_file"`
HtpasswdUserGroups []string `flag:"htpasswd-user-group" cfg:"htpasswd_user_groups"`
Cookie Cookie `cfg:",squash"`
Session SessionOptions `cfg:",squash"`
@@ -199,6 +200,7 @@ func NewFlagSet() *pflag.FlagSet {
flagSet.String("client-secret-file", "", "the file with OAuth Client Secret")
flagSet.String("authenticated-emails-file", "", "authenticate against emails via file (one per line)")
flagSet.String("htpasswd-file", "", "additionally authenticate against a htpasswd file. Entries must be created with \"htpasswd -B\" for bcrypt encryption")
flagSet.StringSlice("htpasswd-user-group", []string{}, "the groups to be set on sessions for htpasswd users (may be given multiple times)")
flagSet.String("proxy-prefix", "/oauth2", "the url root path that this proxy should be nested under (e.g. /<oauth2>/sign_in)")
flagSet.String("ping-path", "/ping", "the ping endpoint that can be used for basic health checks")
flagSet.String("ping-user-agent", "", "special User-Agent that will be used for basic health checks")
+7 -6
View File
@@ -11,9 +11,9 @@ import (
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/logger"
)
func NewBasicAuthSessionLoader(validator basic.Validator) alice.Constructor {
func NewBasicAuthSessionLoader(validator basic.Validator, sessionGroups []string) alice.Constructor {
return func(next http.Handler) http.Handler {
return loadBasicAuthSession(validator, next)
return loadBasicAuthSession(validator, sessionGroups, next)
}
}
@@ -22,7 +22,7 @@ func NewBasicAuthSessionLoader(validator basic.Validator) alice.Constructor {
// If no authorization header is found, or the header is invalid, no session
// will be loaded and the request will be passed to the next handler.
// If a session was loaded by a previous handler, it will not be replaced.
func loadBasicAuthSession(validator basic.Validator, next http.Handler) http.Handler {
func loadBasicAuthSession(validator basic.Validator, sessionGroups []string, next http.Handler) http.Handler {
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
scope := middlewareapi.GetRequestScope(req)
// If scope is nil, this will panic.
@@ -33,7 +33,7 @@ func loadBasicAuthSession(validator basic.Validator, next http.Handler) http.Han
return
}
session, err := getBasicSession(validator, req)
session, err := getBasicSession(validator, sessionGroups, req)
if err != nil {
logger.Errorf("Error retrieving session from token in Authorization header: %v", err)
}
@@ -47,7 +47,7 @@ func loadBasicAuthSession(validator basic.Validator, next http.Handler) http.Han
// getBasicSession attempts to load a basic session from the request.
// If the credentials in the request exist within the htpasswdMap,
// a new session will be created.
func getBasicSession(validator basic.Validator, req *http.Request) (*sessionsapi.SessionState, error) {
func getBasicSession(validator basic.Validator, sessionGroups []string, req *http.Request) (*sessionsapi.SessionState, error) {
auth := req.Header.Get("Authorization")
if auth == "" {
// 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
if validator.Validate(user, password) {
logger.PrintAuthf(user, req, logger.AuthSuccess, "Authenticated via basic auth and HTpasswd File")
return &sessionsapi.SessionState{User: user}, nil
return &sessionsapi.SessionState{User: user, Groups: sessionGroups}, nil
}
logger.PrintAuthf(user, req, logger.AuthFailure, "Invalid authentication via basic auth: not in Htpasswd File")
+8 -1
View File
@@ -26,6 +26,7 @@ var _ = Describe("Basic Auth Session Suite", func() {
type basicAuthSessionLoaderTableInput struct {
authorizationHeader string
sessionGroups []string
existingSession *sessionsapi.SessionState
expectedSession *sessionsapi.SessionState
}
@@ -54,7 +55,7 @@ var _ = Describe("Basic Auth Session Suite", func() {
// Create the handler with a next handler that will capture the session
// from the scope
var gotSession *sessionsapi.SessionState
handler := NewBasicAuthSessionLoader(validator)(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
handler := NewBasicAuthSessionLoader(validator, in.sessionGroups)(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
gotSession = middlewareapi.GetRequestScope(r).Session
}))
handler.ServeHTTP(rw, req)
@@ -111,6 +112,12 @@ var _ = Describe("Basic Auth Session Suite", func() {
existingSession: nil,
expectedSession: &sessionsapi.SessionState{User: "admin"},
}),
Entry("Basic with groups", basicAuthSessionLoaderTableInput{
authorizationHeader: "Basic YWRtaW46QWRtMW4xc3RyJHQwcg==",
sessionGroups: []string{"a", "b"},
existingSession: nil,
expectedSession: &sessionsapi.SessionState{User: "admin", Groups: []string{"a", "b"}},
}),
)
})
})