Log slow LDAP authentication attempts for debugging purposes
This commit is contained in:
parent
6c2a775c9b
commit
3008d1a85c
@ -12,6 +12,9 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"k8s.io/utils/trace"
|
||||||
|
|
||||||
"github.com/go-ldap/ldap/v3"
|
"github.com/go-ldap/ldap/v3"
|
||||||
"k8s.io/apiserver/pkg/authentication/authenticator"
|
"k8s.io/apiserver/pkg/authentication/authenticator"
|
||||||
@ -226,33 +229,42 @@ func (p *Provider) AuthenticateUser(ctx context.Context, username, password stri
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *Provider) authenticateUserImpl(ctx context.Context, username string, bindFunc func(conn Conn, foundUserDN string) error) (*authenticator.Response, bool, error) {
|
func (p *Provider) authenticateUserImpl(ctx context.Context, username string, bindFunc func(conn Conn, foundUserDN string) error) (*authenticator.Response, bool, error) {
|
||||||
|
t := trace.FromContext(ctx).Nest("slow ldap authenticate user attempt", trace.Field{Key: "providerName", Value: p.GetName()})
|
||||||
|
defer t.LogIfLong(500 * time.Millisecond) // to help users debug slow LDAP searches
|
||||||
|
|
||||||
err := p.validateConfig()
|
err := p.validateConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
p.traceAuthFailure(t, err)
|
||||||
return nil, false, err
|
return nil, false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(username) == 0 {
|
if len(username) == 0 {
|
||||||
// Empty passwords are already handled by go-ldap.
|
// Empty passwords are already handled by go-ldap.
|
||||||
|
p.traceAuthFailure(t, fmt.Errorf("empty username"))
|
||||||
return nil, false, nil
|
return nil, false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
conn, err := p.dial(ctx)
|
conn, err := p.dial(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
p.traceAuthFailure(t, err)
|
||||||
return nil, false, fmt.Errorf(`error dialing host "%s": %w`, p.c.Host, err)
|
return nil, false, fmt.Errorf(`error dialing host "%s": %w`, p.c.Host, err)
|
||||||
}
|
}
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
|
|
||||||
err = conn.Bind(p.c.BindUsername, p.c.BindPassword)
|
err = conn.Bind(p.c.BindUsername, p.c.BindPassword)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
p.traceAuthFailure(t, err)
|
||||||
return nil, false, fmt.Errorf(`error binding as "%s" before user search: %w`, p.c.BindUsername, err)
|
return nil, false, fmt.Errorf(`error binding as "%s" before user search: %w`, p.c.BindUsername, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
mappedUsername, mappedUID, err := p.searchAndBindUser(conn, username, bindFunc)
|
mappedUsername, mappedUID, err := p.searchAndBindUser(conn, username, bindFunc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
p.traceAuthFailure(t, err)
|
||||||
return nil, false, err
|
return nil, false, err
|
||||||
}
|
}
|
||||||
if len(mappedUsername) == 0 || len(mappedUID) == 0 {
|
if len(mappedUsername) == 0 || len(mappedUID) == 0 {
|
||||||
// Couldn't find the username or couldn't bind using the password.
|
// Couldn't find the username or couldn't bind using the password.
|
||||||
|
p.traceAuthFailure(t, fmt.Errorf("bad username or password"))
|
||||||
return nil, false, nil
|
return nil, false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -263,6 +275,7 @@ func (p *Provider) authenticateUserImpl(ctx context.Context, username string, bi
|
|||||||
Groups: []string{}, // Support for group search coming soon.
|
Groups: []string{}, // Support for group search coming soon.
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
p.traceAuthSuccess(t)
|
||||||
return response, true, nil
|
return response, true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -384,3 +397,16 @@ func (p *Provider) getSearchResultAttributeValue(attributeName string, fromUserE
|
|||||||
|
|
||||||
return attributeValue, nil
|
return attributeValue, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Provider) traceAuthFailure(t *trace.Trace, err error) {
|
||||||
|
t.Step("authentication failed",
|
||||||
|
trace.Field{Key: "authenticated", Value: false},
|
||||||
|
trace.Field{Key: "reason", Value: err.Error()},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Provider) traceAuthSuccess(t *trace.Trace) {
|
||||||
|
t.Step("authentication succeeded",
|
||||||
|
trace.Field{Key: "authenticated", Value: true},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user