1
0
mirror of https://github.com/oauth2-proxy/oauth2-proxy.git synced 2025-06-27 00:51:33 +02:00

implement an error alert message for invalid basic auth credentials

This commit is contained in:
Alexandru Ciobanu
2022-06-30 18:10:02 +03:00
parent db74661e10
commit cbda3cf618
4 changed files with 49 additions and 13 deletions

View File

@ -568,26 +568,26 @@ func (p *OAuthProxy) SignInPage(rw http.ResponseWriter, req *http.Request, code
redirectURL = "/" redirectURL = "/"
} }
p.pageWriter.WriteSignInPage(rw, req, redirectURL) p.pageWriter.WriteSignInPage(rw, req, redirectURL, code)
} }
// ManualSignIn handles basic auth logins to the proxy // ManualSignIn handles basic auth logins to the proxy
func (p *OAuthProxy) ManualSignIn(req *http.Request) (string, bool) { func (p *OAuthProxy) ManualSignIn(req *http.Request) (string, bool, int) {
if req.Method != "POST" || p.basicAuthValidator == nil { if req.Method != "POST" || p.basicAuthValidator == nil {
return "", false return "", false, http.StatusOK
} }
user := req.FormValue("username") user := req.FormValue("username")
passwd := req.FormValue("password") passwd := req.FormValue("password")
if user == "" { if user == "" {
return "", false return "", false, http.StatusBadRequest
} }
// check auth // check auth
if p.basicAuthValidator.Validate(user, passwd) { if p.basicAuthValidator.Validate(user, passwd) {
logger.PrintAuthf(user, req, logger.AuthSuccess, "Authenticated via HtpasswdFile") logger.PrintAuthf(user, req, logger.AuthSuccess, "Authenticated via HtpasswdFile")
return user, true return user, true, http.StatusOK
} }
logger.PrintAuthf(user, req, logger.AuthFailure, "Invalid authentication via HtpasswdFile") logger.PrintAuthf(user, req, logger.AuthFailure, "Invalid authentication via HtpasswdFile")
return "", false return "", false, http.StatusUnauthorized
} }
// SignIn serves a page prompting users to sign in // SignIn serves a page prompting users to sign in
@ -599,7 +599,7 @@ func (p *OAuthProxy) SignIn(rw http.ResponseWriter, req *http.Request) {
return return
} }
user, ok := p.ManualSignIn(req) user, ok, statusCode := p.ManualSignIn(req)
if ok { if ok {
session := &sessionsapi.SessionState{User: user, Groups: p.basicAuthGroups} session := &sessionsapi.SessionState{User: user, Groups: p.basicAuthGroups}
err = p.SaveSession(rw, req, session) err = p.SaveSession(rw, req, session)
@ -614,7 +614,7 @@ func (p *OAuthProxy) SignIn(rw http.ResponseWriter, req *http.Request) {
p.OAuthStart(rw, req) p.OAuthStart(rw, req)
} else { } else {
// TODO - should we pass on /oauth2/sign_in query params to /oauth2/start? // TODO - should we pass on /oauth2/sign_in query params to /oauth2/start?
p.SignInPage(rw, req, http.StatusOK) p.SignInPage(rw, req, statusCode)
} }
} }
} }

View File

@ -10,7 +10,7 @@ import (
// It can also be used to write errors for the http.ReverseProxy used in the // It can also be used to write errors for the http.ReverseProxy used in the
// upstream package. // upstream package.
type Writer interface { type Writer interface {
WriteSignInPage(rw http.ResponseWriter, req *http.Request, redirectURL string) WriteSignInPage(rw http.ResponseWriter, req *http.Request, redirectURL string, statusCode int)
WriteErrorPage(rw http.ResponseWriter, opts ErrorPageOpts) WriteErrorPage(rw http.ResponseWriter, opts ErrorPageOpts)
ProxyErrorHandler(rw http.ResponseWriter, req *http.Request, proxyErr error) ProxyErrorHandler(rw http.ResponseWriter, req *http.Request, proxyErr error)
WriteRobotsTxt(rw http.ResponseWriter, req *http.Request) WriteRobotsTxt(rw http.ResponseWriter, req *http.Request)
@ -108,7 +108,7 @@ func NewWriter(opts Opts) (Writer, error) {
// If any of the funcs are not provided, a default implementation will be used. // If any of the funcs are not provided, a default implementation will be used.
// This is primarily for us in testing. // This is primarily for us in testing.
type WriterFuncs struct { type WriterFuncs struct {
SignInPageFunc func(rw http.ResponseWriter, req *http.Request, redirectURL string) SignInPageFunc func(rw http.ResponseWriter, req *http.Request, redirectURL string, statusCode int)
ErrorPageFunc func(rw http.ResponseWriter, opts ErrorPageOpts) ErrorPageFunc func(rw http.ResponseWriter, opts ErrorPageOpts)
ProxyErrorFunc func(rw http.ResponseWriter, req *http.Request, proxyErr error) ProxyErrorFunc func(rw http.ResponseWriter, req *http.Request, proxyErr error)
RobotsTxtfunc func(rw http.ResponseWriter, req *http.Request) RobotsTxtfunc func(rw http.ResponseWriter, req *http.Request)
@ -117,9 +117,9 @@ type WriterFuncs struct {
// WriteSignInPage implements the Writer interface. // WriteSignInPage implements the Writer interface.
// If the SignInPageFunc is provided, this will be used, else a default // If the SignInPageFunc is provided, this will be used, else a default
// implementation will be used. // implementation will be used.
func (w *WriterFuncs) WriteSignInPage(rw http.ResponseWriter, req *http.Request, redirectURL string) { func (w *WriterFuncs) WriteSignInPage(rw http.ResponseWriter, req *http.Request, redirectURL string, statusCode int) {
if w.SignInPageFunc != nil { if w.SignInPageFunc != nil {
w.SignInPageFunc(rw, req, redirectURL) w.SignInPageFunc(rw, req, redirectURL, statusCode)
return return
} }

View File

@ -18,6 +18,28 @@
.logo-box { .logo-box {
margin: 1.5rem 3rem; margin: 1.5rem 3rem;
} }
.alert {
padding: 5px;
background-color: #f44336; /* Red */
color: white;
margin-bottom: 5px;
border-radius: 5px
}
/* The close button */
.closebtn {
margin-left: 10px;
color: white;
font-weight: bold;
float: right;
font-size: 22px;
line-height: 20px;
cursor: pointer;
transition: 0.3s;
}
/* When moving the mouse over the close button */
.closebtn:hover {
color: black;
}
footer a { footer a {
text-decoration: underline; text-decoration: underline;
} }
@ -62,6 +84,18 @@
<button class="button is-primary">Sign in</button> <button class="button is-primary">Sign in</button>
</form> </form>
{{ end }} {{ end }}
{{ if eq .StatusCode 400 401 }}
<div class="alert">
<span class="closebtn" onclick="this.parentElement.style.display='none';">&times;</span>
{{ if eq .StatusCode 400 }}
{{.StatusCode}}: Username cannot be empty
{{ else }}
{{.StatusCode}}: Invalid Username or Password
{{ end }}
</div>
{{ end }}
</div> </div>
</section> </section>

View File

@ -54,12 +54,13 @@ type signInPageWriter struct {
// WriteSignInPage writes the sign-in page to the given response writer. // WriteSignInPage writes the sign-in page to the given response writer.
// It uses the redirectURL to be able to set the final destination for the user post login. // It uses the redirectURL to be able to set the final destination for the user post login.
func (s *signInPageWriter) WriteSignInPage(rw http.ResponseWriter, req *http.Request, redirectURL string) { func (s *signInPageWriter) WriteSignInPage(rw http.ResponseWriter, req *http.Request, redirectURL string, statusCode int) {
// We allow unescaped template.HTML since it is user configured options // We allow unescaped template.HTML since it is user configured options
/* #nosec G203 */ /* #nosec G203 */
t := struct { t := struct {
ProviderName string ProviderName string
SignInMessage template.HTML SignInMessage template.HTML
StatusCode int
CustomLogin bool CustomLogin bool
Redirect string Redirect string
Version string Version string
@ -69,6 +70,7 @@ func (s *signInPageWriter) WriteSignInPage(rw http.ResponseWriter, req *http.Req
}{ }{
ProviderName: s.providerName, ProviderName: s.providerName,
SignInMessage: template.HTML(s.signInMessage), SignInMessage: template.HTML(s.signInMessage),
StatusCode: statusCode,
CustomLogin: s.displayLoginForm, CustomLogin: s.displayLoginForm,
Redirect: redirectURL, Redirect: redirectURL,
Version: s.version, Version: s.version,