mirror of https://github.com/k3s-io/k3s
Merge pull request #41775 from CaoShuFeng/username_password_401_403
Automatic merge from submit-queue Ensure invalid username/password returns 401 error, not 403 If a user attempts to use basic auth, and the username/password combination is rejected, the authenticator should return an error. This distinguishes requests that did not provide username/passwrod (and are unauthenticated without error) from ones that attempted to, and failed. Related to: https://github.com/kubernetes/kubernetes/pull/39408pull/6/head
commit
7d4fe5f3cd
|
@ -209,7 +209,8 @@ func (config AuthenticatorConfig) New() (authenticator.Request, *spec.SecurityDe
|
||||||
authenticator = group.NewAuthenticatedGroupAdder(authenticator)
|
authenticator = group.NewAuthenticatedGroupAdder(authenticator)
|
||||||
|
|
||||||
if config.Anonymous {
|
if config.Anonymous {
|
||||||
// If the authenticator chain returns an error, return an error (don't consider a bad bearer token anonymous).
|
// If the authenticator chain returns an error, return an error (don't consider a bad bearer token
|
||||||
|
// or invalid username/password combination anonymous).
|
||||||
authenticator = union.NewFailOnError(authenticator, anonymous.NewAuthenticator())
|
authenticator = union.NewFailOnError(authenticator, anonymous.NewAuthenticator())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ limitations under the License.
|
||||||
package basicauth
|
package basicauth
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"k8s.io/apiserver/pkg/authentication/authenticator"
|
"k8s.io/apiserver/pkg/authentication/authenticator"
|
||||||
|
@ -33,11 +34,21 @@ func New(auth authenticator.Password) *Authenticator {
|
||||||
return &Authenticator{auth}
|
return &Authenticator{auth}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var errInvalidAuth = errors.New("invalid username/password combination")
|
||||||
|
|
||||||
// AuthenticateRequest authenticates the request using the "Authorization: Basic" header in the request
|
// AuthenticateRequest authenticates the request using the "Authorization: Basic" header in the request
|
||||||
func (a *Authenticator) AuthenticateRequest(req *http.Request) (user.Info, bool, error) {
|
func (a *Authenticator) AuthenticateRequest(req *http.Request) (user.Info, bool, error) {
|
||||||
username, password, found := req.BasicAuth()
|
username, password, found := req.BasicAuth()
|
||||||
if !found {
|
if !found {
|
||||||
return nil, false, nil
|
return nil, false, nil
|
||||||
}
|
}
|
||||||
return a.auth.AuthenticatePassword(username, password)
|
|
||||||
|
user, ok, err := a.auth.AuthenticatePassword(username, password)
|
||||||
|
|
||||||
|
// If the password authenticator didn't error, provide a default error
|
||||||
|
if !ok && err == nil {
|
||||||
|
err = errInvalidAuth
|
||||||
|
}
|
||||||
|
|
||||||
|
return user, ok, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,11 +60,13 @@ func TestBasicAuth(t *testing.T) {
|
||||||
ExpectedCalled: true,
|
ExpectedCalled: true,
|
||||||
ExpectedUsername: "user_with_empty_password",
|
ExpectedUsername: "user_with_empty_password",
|
||||||
ExpectedPassword: "",
|
ExpectedPassword: "",
|
||||||
|
ExpectedErr: true,
|
||||||
},
|
},
|
||||||
"valid basic header": {
|
"valid basic header": {
|
||||||
ExpectedCalled: true,
|
ExpectedCalled: true,
|
||||||
ExpectedUsername: "myuser",
|
ExpectedUsername: "myuser",
|
||||||
ExpectedPassword: "mypassword:withcolon",
|
ExpectedPassword: "mypassword:withcolon",
|
||||||
|
ExpectedErr: true,
|
||||||
},
|
},
|
||||||
"password auth returned user": {
|
"password auth returned user": {
|
||||||
Password: testPassword{User: &user.DefaultInfo{Name: "returneduser"}, OK: true},
|
Password: testPassword{User: &user.DefaultInfo{Name: "returneduser"}, OK: true},
|
||||||
|
|
Loading…
Reference in New Issue