Authn: Fix password client fallthrough (#63244)

* fix password client fallthrough

* fix grafana client String
This commit is contained in:
Jo 2023-02-12 14:42:47 +01:00 committed by GitHub
parent 6ca9e5b440
commit 554dc9b97d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 24 additions and 11 deletions

View File

@ -21,6 +21,10 @@ type Basic struct {
client authn.PasswordClient client authn.PasswordClient
} }
func (c *Basic) String() string {
return c.Name()
}
func (c *Basic) Name() string { func (c *Basic) Name() string {
return authn.ClientBasic return authn.ClientBasic
} }

View File

@ -26,6 +26,10 @@ type Grafana struct {
userService user.Service userService user.Service
} }
func (c *Grafana) String() string {
return "grafana"
}
func (c *Grafana) AuthenticateProxy(ctx context.Context, r *authn.Request, username string, additional map[string]string) (*authn.Identity, error) { func (c *Grafana) AuthenticateProxy(ctx context.Context, r *authn.Request, username string, additional map[string]string) (*authn.Identity, error) {
identity := &authn.Identity{ identity := &authn.Identity{
AuthModule: login.AuthProxyAuthModule, AuthModule: login.AuthProxyAuthModule,

View File

@ -27,6 +27,10 @@ type LDAP struct {
service ldapService service ldapService
} }
func (c *LDAP) String() string {
return "ldap"
}
func (c *LDAP) AuthenticateProxy(ctx context.Context, r *authn.Request, username string, _ map[string]string) (*authn.Identity, error) { func (c *LDAP) AuthenticateProxy(ctx context.Context, r *authn.Request, username string, _ map[string]string) (*authn.Identity, error) {
info, err := c.service.User(username) info, err := c.service.User(username)
if errors.Is(err, multildap.ErrDidNotFindUser) { if errors.Is(err, multildap.ErrDidNotFindUser) {

View File

@ -4,6 +4,9 @@ import (
"context" "context"
"errors" "errors"
"github.com/hashicorp/go-multierror"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/services/authn" "github.com/grafana/grafana/pkg/services/authn"
"github.com/grafana/grafana/pkg/services/loginattempt" "github.com/grafana/grafana/pkg/services/loginattempt"
"github.com/grafana/grafana/pkg/util/errutil" "github.com/grafana/grafana/pkg/util/errutil"
@ -20,12 +23,13 @@ var (
var _ authn.PasswordClient = new(Password) var _ authn.PasswordClient = new(Password)
func ProvidePassword(loginAttempts loginattempt.Service, clients ...authn.PasswordClient) *Password { func ProvidePassword(loginAttempts loginattempt.Service, clients ...authn.PasswordClient) *Password {
return &Password{loginAttempts, clients} return &Password{loginAttempts, clients, log.New("authn.password")}
} }
type Password struct { type Password struct {
loginAttempts loginattempt.Service loginAttempts loginattempt.Service
clients []authn.PasswordClient clients []authn.PasswordClient
log log.Logger
} }
func (c *Password) AuthenticatePassword(ctx context.Context, r *authn.Request, username, password string) (*authn.Identity, error) { func (c *Password) AuthenticatePassword(ctx context.Context, r *authn.Request, username, password string) (*authn.Identity, error) {
@ -43,25 +47,22 @@ func (c *Password) AuthenticatePassword(ctx context.Context, r *authn.Request, u
return nil, errEmptyPassword.Errorf("no password provided") return nil, errEmptyPassword.Errorf("no password provided")
} }
var clientErr error var clientErrs error
for _, pwClient := range c.clients { for _, pwClient := range c.clients {
var identity *authn.Identity identity, clientErr := pwClient.AuthenticatePassword(ctx, r, username, password)
identity, clientErr = pwClient.AuthenticatePassword(ctx, r, username, password) clientErrs = multierror.Append(clientErrs, clientErr)
// for invalid password or if the identity is not found by a client continue to next one // for invalid password or if the identity is not found by a client continue to next one
if errors.Is(clientErr, errInvalidPassword) || errors.Is(clientErr, errIdentityNotFound) {
continue
}
if clientErr != nil { if clientErr != nil {
return nil, errPasswordAuthFailed.Errorf("failed to authenticate identity: %w", clientErr) c.log.Warn("failed to authenticate password identity", "client", pwClient, "error", clientErr)
continue
} }
return identity, nil return identity, nil
} }
if errors.Is(clientErr, errInvalidPassword) { if errors.Is(clientErrs, errInvalidPassword) {
_ = c.loginAttempts.Add(ctx, username, web.RemoteAddr(r.HTTPRequest)) _ = c.loginAttempts.Add(ctx, username, web.RemoteAddr(r.HTTPRequest))
} }
return nil, errPasswordAuthFailed.Errorf("failed to authenticate identity: %w", clientErr) return nil, errPasswordAuthFailed.Errorf("failed to authenticate identity: %w", clientErrs)
} }