@@ -22,6 +22,7 @@ import (
22 ipapi "github.com/oauth2-proxy/oauth2-proxy/pkg/apis/ip"
22 ipapi "github.com/oauth2-proxy/oauth2-proxy/pkg/apis/ip"
23 "github.com/oauth2-proxy/oauth2-proxy/pkg/apis/options"
23 "github.com/oauth2-proxy/oauth2-proxy/pkg/apis/options"
24 sessionsapi "github.com/oauth2-proxy/oauth2-proxy/pkg/apis/sessions"
24 sessionsapi "github.com/oauth2-proxy/oauth2-proxy/pkg/apis/sessions"
25+ "github.com/oauth2-proxy/oauth2-proxy/pkg/authentication/basic"
25 "github.com/oauth2-proxy/oauth2-proxy/pkg/cookies"
26 "github.com/oauth2-proxy/oauth2-proxy/pkg/cookies"
26 "github.com/oauth2-proxy/oauth2-proxy/pkg/encryption"
27 "github.com/oauth2-proxy/oauth2-proxy/pkg/encryption"
27 "github.com/oauth2-proxy/oauth2-proxy/pkg/ip"
28 "github.com/oauth2-proxy/oauth2-proxy/pkg/ip"
@@ -96,8 +97,8 @@ type OAuthProxy struct {
96 sessionStore sessionsapi.SessionStore
97 sessionStore sessionsapi.SessionStore
97 ProxyPrefix string
98 ProxyPrefix string
98 SignInMessage string
99 SignInMessage string
99− HtpasswdFile *HtpasswdFile
100+ basicAuthValidator basic.Validator
100− DisplayHtpasswdForm bool
101+ displayHtpasswdForm bool
101 serveMux http.Handler
102 serveMux http.Handler
102 SetXAuthRequest bool
103 SetXAuthRequest bool
103 PassBasicAuth bool
104 PassBasicAuth bool
@@ -314,6 +315,16 @@ func NewOAuthProxy(opts *options.Options, validator func(string) bool) (*OAuthPr
318+ var basicAuthValidator basic.Validator
319+ if opts.HtpasswdFile != "" {
320+ logger.Printf("using htpasswd file: %s", opts.HtpasswdFile)
322+ basicAuthValidator, err = basic.NewHTPasswdValidator(opts.HtpasswdFile)
324+ return nil, fmt.Errorf("could not load htpasswdfile: %v", err)
317 return &OAuthProxy{
328 return &OAuthProxy{
318 CookieName: opts.Cookie.Name,
329 CookieName: opts.Cookie.Name,
319 CSRFCookieName: fmt.Sprintf("%v_%v", opts.Cookie.Name, "csrf"),
330 CSRFCookieName: fmt.Sprintf("%v_%v", opts.Cookie.Name, "csrf"),
@@ -364,6 +375,9 @@ func NewOAuthProxy(opts *options.Options, validator func(string) bool) (*OAuthPr
364 trustedIPs: trustedIPs,
375 trustedIPs: trustedIPs,
365 Banner: opts.Banner,
376 Banner: opts.Banner,
366 Footer: opts.Footer,
377 Footer: opts.Footer,
379+ basicAuthValidator: basicAuthValidator,
380+ displayHtpasswdForm: basicAuthValidator != nil,
@@ -386,10 +400,6 @@ func (p *OAuthProxy) GetRedirectURI(host string) string {
386 return u.String()
400 return u.String()
389−func (p *OAuthProxy) displayCustomLoginForm() bool {
390− return p.HtpasswdFile != nil && p.DisplayHtpasswdForm
393func (p *OAuthProxy) redeemCode(ctx context.Context, host, code string) (s *sessionsapi.SessionState, err error) {
403func (p *OAuthProxy) redeemCode(ctx context.Context, host, code string) (s *sessionsapi.SessionState, err error) {
394 if code == "" {
404 if code == "" {
395 return nil, errors.New("missing code")
405 return nil, errors.New("missing code")
@@ -526,7 +536,7 @@ func (p *OAuthProxy) SignInPage(rw http.ResponseWriter, req *http.Request, code
527 ProviderName: p.provider.Data().ProviderName,
537 ProviderName: p.provider.Data().ProviderName,
528 SignInMessage: template.HTML(p.SignInMessage),
538 SignInMessage: template.HTML(p.SignInMessage),
529− CustomLogin: p.displayCustomLoginForm(),
539+ CustomLogin: p.displayHtpasswdForm,
530 Redirect: redirectURL,
540 Redirect: redirectURL,
531 Version: VERSION,
541 Version: VERSION,
532 ProxyPrefix: p.ProxyPrefix,
542 ProxyPrefix: p.ProxyPrefix,
@@ -540,7 +550,7 @@ func (p *OAuthProxy) SignInPage(rw http.ResponseWriter, req *http.Request, code
541// ManualSignIn handles basic auth logins to the proxy
551// ManualSignIn handles basic auth logins to the proxy
542func (p *OAuthProxy) ManualSignIn(rw http.ResponseWriter, req *http.Request) (string, bool) {
552func (p *OAuthProxy) ManualSignIn(rw http.ResponseWriter, req *http.Request) (string, bool) {
543− if req.Method != "POST" || p.HtpasswdFile == nil {
553+ if req.Method != "POST" || p.basicAuthValidator == nil {
544 return "", false
554 return "", false
546 user := req.FormValue("username")
556 user := req.FormValue("username")
@@ -549,7 +559,7 @@ func (p *OAuthProxy) ManualSignIn(rw http.ResponseWriter, req *http.Request) (st
549 return "", false
559 return "", false
551 // check auth
561 // check auth
552− if p.HtpasswdFile.Validate(user, passwd) {
562+ if p.basicAuthValidator.Validate(user, passwd) {
553 logger.PrintAuthf(user, req, logger.AuthSuccess, "Authenticated via HtpasswdFile")
563 logger.PrintAuthf(user, req, logger.AuthSuccess, "Authenticated via HtpasswdFile")
554 return user, true
564 return user, true
@@ -1159,7 +1169,7 @@ func (p *OAuthProxy) stripAuthHeaders(req *http.Request) {
1159// CheckBasicAuth checks the requests Authorization header for basic auth
1169// CheckBasicAuth checks the requests Authorization header for basic auth
1160// credentials and authenticates these against the proxies HtpasswdFile
1170// credentials and authenticates these against the proxies HtpasswdFile
1161func (p *OAuthProxy) CheckBasicAuth(req *http.Request) (*sessionsapi.SessionState, error) {
1171func (p *OAuthProxy) CheckBasicAuth(req *http.Request) (*sessionsapi.SessionState, error) {
1162− if p.HtpasswdFile == nil {
1172+ if p.basicAuthValidator == nil {
1163 return nil, nil
1173 return nil, nil
1165 auth := req.Header.Get("Authorization")
1175 auth := req.Header.Get("Authorization")
@@ -1178,7 +1188,7 @@ func (p *OAuthProxy) CheckBasicAuth(req *http.Request) (*sessionsapi.SessionStat
1178 if len(pair) != 2 {
1188 if len(pair) != 2 {
1179 return nil, fmt.Errorf("invalid format %s", b)
1189 return nil, fmt.Errorf("invalid format %s", b)
1181− if p.HtpasswdFile.Validate(pair[0], pair[1]) {
1191+ if p.basicAuthValidator.Validate(pair[0], pair[1]) {
1182 logger.PrintAuthf(pair[0], req, logger.AuthSuccess, "Authenticated via basic auth and HTpasswd File")
1192 logger.PrintAuthf(pair[0], req, logger.AuthSuccess, "Authenticated via basic auth and HTpasswd File")
1183 return &sessionsapi.SessionState{User: pair[0]}, nil
1193 return &sessionsapi.SessionState{User: pair[0]}, nil