Provide username in log data on auth failure
This commit is contained in:
parent
8d827f98da
commit
8d3d5c068c
3 changed files with 87 additions and 26 deletions
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -62,21 +62,32 @@ 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()
|
||||||
logger.Debug("Authentication failed")
|
if ok {
|
||||||
tracing.SetErrorWithEvent(req, "Authentication failed")
|
secret := b.auth.Secrets(user, b.auth.Realm)
|
||||||
b.auth.RequireAuth(rw, req)
|
if secret == "" || !goauth.CheckSecret(password, secret) {
|
||||||
} else {
|
ok = false
|
||||||
logger.Debug("Authentication succeeded")
|
}
|
||||||
req.URL.User = url.User(username)
|
}
|
||||||
|
|
||||||
logData := accesslog.GetLogData(req)
|
logData := accesslog.GetLogData(req)
|
||||||
if logData != nil {
|
if logData != nil {
|
||||||
logData.Core[accesslog.ClientUsername] = username
|
logData.Core[accesslog.ClientUsername] = user
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
logger.Debug("Authentication failed")
|
||||||
|
tracing.SetErrorWithEvent(req, "Authentication failed")
|
||||||
|
|
||||||
|
b.auth.RequireAuth(rw, req)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Debug("Authentication succeeded")
|
||||||
|
req.URL.User = url.User(user)
|
||||||
|
|
||||||
if b.headerField != "" {
|
if b.headerField != "" {
|
||||||
req.Header[b.headerField] = []string{username}
|
req.Header[b.headerField] = []string{user}
|
||||||
}
|
}
|
||||||
|
|
||||||
if b.removeHeader {
|
if b.removeHeader {
|
||||||
|
@ -85,7 +96,6 @@ func (b *basicAuth) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||||
}
|
}
|
||||||
b.next.ServeHTTP(rw, req)
|
b.next.ServeHTTP(rw, req)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
func (b *basicAuth) secretBasic(user, realm string) string {
|
func (b *basicAuth) secretBasic(user, realm string) string {
|
||||||
if secret, ok := b.users[user]; ok {
|
if secret, ok := b.users[user]; ok {
|
||||||
|
|
|
@ -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")
|
||||||
|
|
Loading…
Reference in a new issue