Provide username in log data on auth failure

This commit is contained in:
Romain 2020-06-18 16:02:04 +02:00 committed by GitHub
parent 8d827f98da
commit 8d3d5c068c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 87 additions and 26 deletions

View file

@ -111,6 +111,20 @@ func (s *AccessLogSuite) TestAccessLogAuthFrontend(c *check.C) {
routerName: "rt-authFrontend", routerName: "rt-authFrontend",
serviceURL: "-", serviceURL: "-",
}, },
{
formatOnly: false,
code: "401",
user: "test",
routerName: "rt-authFrontend",
serviceURL: "-",
},
{
formatOnly: false,
code: "200",
user: "test",
routerName: "rt-authFrontend",
serviceURL: "http://172.17.0",
},
} }
// Start Traefik // Start Traefik
@ -130,7 +144,7 @@ func (s *AccessLogSuite) TestAccessLogAuthFrontend(c *check.C) {
// Verify Traefik started OK // Verify Traefik started OK
checkTraefikStarted(c) checkTraefikStarted(c)
// Test auth frontend // Test auth entrypoint
req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8006/", nil) req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8006/", nil)
c.Assert(err, checker.IsNil) c.Assert(err, checker.IsNil)
req.Host = "frontend.auth.docker.local" req.Host = "frontend.auth.docker.local"
@ -138,6 +152,16 @@ func (s *AccessLogSuite) TestAccessLogAuthFrontend(c *check.C) {
err = try.Request(req, 500*time.Millisecond, try.StatusCodeIs(http.StatusUnauthorized), try.HasBody()) err = try.Request(req, 500*time.Millisecond, try.StatusCodeIs(http.StatusUnauthorized), try.HasBody())
c.Assert(err, checker.IsNil) c.Assert(err, checker.IsNil)
req.SetBasicAuth("test", "")
err = try.Request(req, 500*time.Millisecond, try.StatusCodeIs(http.StatusUnauthorized), try.HasBody())
c.Assert(err, checker.IsNil)
req.SetBasicAuth("test", "test")
err = try.Request(req, 500*time.Millisecond, try.StatusCodeIs(http.StatusOK), try.HasBody())
c.Assert(err, checker.IsNil)
// Verify access.log output as expected // Verify access.log output as expected
count := checkAccessLogExactValuesOutput(c, expected) count := checkAccessLogExactValuesOutput(c, expected)
@ -158,6 +182,13 @@ func (s *AccessLogSuite) TestAccessLogDigestAuthMiddleware(c *check.C) {
routerName: "rt-digestAuthMiddleware", routerName: "rt-digestAuthMiddleware",
serviceURL: "-", serviceURL: "-",
}, },
{
formatOnly: false,
code: "401",
user: "test",
routerName: "rt-digestAuthMiddleware",
serviceURL: "-",
},
{ {
formatOnly: false, formatOnly: false,
code: "200", code: "200",
@ -192,15 +223,22 @@ func (s *AccessLogSuite) TestAccessLogDigestAuthMiddleware(c *check.C) {
resp, err := try.ResponseUntilStatusCode(req, 500*time.Millisecond, http.StatusUnauthorized) resp, err := try.ResponseUntilStatusCode(req, 500*time.Millisecond, http.StatusUnauthorized)
c.Assert(err, checker.IsNil) c.Assert(err, checker.IsNil)
digestParts := digestParts(resp) digest := digestParts(resp)
digestParts["uri"] = "/" digest["uri"] = "/"
digestParts["method"] = http.MethodGet digest["method"] = http.MethodGet
digestParts["username"] = "test" digest["username"] = "test"
digestParts["password"] = "test" digest["password"] = "wrong"
req.Header.Set("Authorization", getDigestAuthorization(digestParts)) req.Header.Set("Authorization", getDigestAuthorization(digest))
req.Header.Set("Content-Type", "application/json") req.Header.Set("Content-Type", "application/json")
err = try.Request(req, 500*time.Millisecond, try.StatusCodeIs(http.StatusUnauthorized), try.HasBody())
c.Assert(err, checker.IsNil)
digest["password"] = "test"
req.Header.Set("Authorization", getDigestAuthorization(digest))
err = try.Request(req, 500*time.Millisecond, try.StatusCodeIs(http.StatusOK), try.HasBody()) err = try.Request(req, 500*time.Millisecond, try.StatusCodeIs(http.StatusOK), try.HasBody())
c.Assert(err, checker.IsNil) c.Assert(err, checker.IsNil)

View file

@ -62,29 +62,39 @@ func (b *basicAuth) GetTracingInformation() (string, ext.SpanKindEnum) {
func (b *basicAuth) ServeHTTP(rw http.ResponseWriter, req *http.Request) { func (b *basicAuth) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
logger := log.FromContext(middlewares.GetLoggerCtx(req.Context(), b.name, basicTypeName)) logger := log.FromContext(middlewares.GetLoggerCtx(req.Context(), b.name, basicTypeName))
if username := b.auth.CheckAuth(req); username == "" { user, password, ok := req.BasicAuth()
if ok {
secret := b.auth.Secrets(user, b.auth.Realm)
if secret == "" || !goauth.CheckSecret(password, secret) {
ok = false
}
}
logData := accesslog.GetLogData(req)
if logData != nil {
logData.Core[accesslog.ClientUsername] = user
}
if !ok {
logger.Debug("Authentication failed") logger.Debug("Authentication failed")
tracing.SetErrorWithEvent(req, "Authentication failed") tracing.SetErrorWithEvent(req, "Authentication failed")
b.auth.RequireAuth(rw, req) b.auth.RequireAuth(rw, req)
} else { return
logger.Debug("Authentication succeeded")
req.URL.User = url.User(username)
logData := accesslog.GetLogData(req)
if logData != nil {
logData.Core[accesslog.ClientUsername] = username
}
if b.headerField != "" {
req.Header[b.headerField] = []string{username}
}
if b.removeHeader {
logger.Debug("Removing authorization header")
req.Header.Del(authorizationHeader)
}
b.next.ServeHTTP(rw, req)
} }
logger.Debug("Authentication succeeded")
req.URL.User = url.User(user)
if b.headerField != "" {
req.Header[b.headerField] = []string{user}
}
if b.removeHeader {
logger.Debug("Removing authorization header")
req.Header.Del(authorizationHeader)
}
b.next.ServeHTTP(rw, req)
} }
func (b *basicAuth) secretBasic(user, realm string) string { func (b *basicAuth) secretBasic(user, realm string) string {

View file

@ -63,6 +63,19 @@ func (d *digestAuth) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
username, authinfo := d.auth.CheckAuth(req) username, authinfo := d.auth.CheckAuth(req)
if username == "" { if username == "" {
headerField := d.headerField
if d.headerField == "" {
headerField = "Authorization"
}
auth := goauth.DigestAuthParams(req.Header.Get(headerField))
if auth["username"] != "" {
logData := accesslog.GetLogData(req)
if logData != nil {
logData.Core[accesslog.ClientUsername] = auth["username"]
}
}
if authinfo != nil && *authinfo == "stale" { if authinfo != nil && *authinfo == "stale" {
logger.Debug("Digest authentication failed, possibly because out of order requests") logger.Debug("Digest authentication failed, possibly because out of order requests")
tracing.SetErrorWithEvent(req, "Digest authentication failed, possibly because out of order requests") tracing.SetErrorWithEvent(req, "Digest authentication failed, possibly because out of order requests")