diff --git a/staging/src/k8s.io/apiserver/pkg/authentication/request/bearertoken/bearertoken.go b/staging/src/k8s.io/apiserver/pkg/authentication/request/bearertoken/bearertoken.go index 292b4f57d07..68c6ad918ae 100644 --- a/staging/src/k8s.io/apiserver/pkg/authentication/request/bearertoken/bearertoken.go +++ b/staging/src/k8s.io/apiserver/pkg/authentication/request/bearertoken/bearertoken.go @@ -22,6 +22,11 @@ import ( "strings" "k8s.io/apiserver/pkg/authentication/authenticator" + "k8s.io/apiserver/pkg/warning" +) + +const ( + invalidTokenWithSpaceWarning = "the provided Authorization header contains extra space before the bearer token, and is ignored" ) type Authenticator struct { @@ -48,6 +53,10 @@ func (a *Authenticator) AuthenticateRequest(req *http.Request) (*authenticator.R // Empty bearer tokens aren't valid if len(token) == 0 { + // The space before the token case + if len(parts) == 3 { + warning.AddWarning(req.Context(), "", invalidTokenWithSpaceWarning) + } return nil, false, nil } diff --git a/staging/src/k8s.io/apiserver/pkg/authentication/request/bearertoken/bearertoken_test.go b/staging/src/k8s.io/apiserver/pkg/authentication/request/bearertoken/bearertoken_test.go index 5e982d5576f..d1e00babb87 100644 --- a/staging/src/k8s.io/apiserver/pkg/authentication/request/bearertoken/bearertoken_test.go +++ b/staging/src/k8s.io/apiserver/pkg/authentication/request/bearertoken/bearertoken_test.go @@ -25,6 +25,8 @@ import ( "k8s.io/apiserver/pkg/authentication/authenticator" "k8s.io/apiserver/pkg/authentication/user" + genericapirequest "k8s.io/apiserver/pkg/endpoints/request" + "k8s.io/apiserver/pkg/warning" ) func TestAuthenticateRequest(t *testing.T) { @@ -128,6 +130,23 @@ func TestAuthenticateRequestBadValue(t *testing.T) { } } +type dummyRecorder struct { + agent string + text string +} + +func (r *dummyRecorder) AddWarning(agent, text string) { + r.agent = agent + r.text = text + return +} + +func (r *dummyRecorder) getWarning() string { + return r.text +} + +var _ warning.Recorder = &dummyRecorder{} + func TestBearerToken(t *testing.T) { tests := map[string]struct { AuthorizationHeaders []string @@ -137,6 +156,7 @@ func TestBearerToken(t *testing.T) { ExpectedOK bool ExpectedErr bool ExpectedAuthorizationHeaders []string + ExpectedRecordedWarning string }{ "no header": { AuthorizationHeaders: nil, @@ -184,6 +204,14 @@ func TestBearerToken(t *testing.T) { ExpectedErr: true, ExpectedAuthorizationHeaders: []string{"Bearer 123"}, }, + "valid bearer token with a space": { + AuthorizationHeaders: []string{"Bearer token"}, + ExpectedUserName: "", + ExpectedOK: false, + ExpectedErr: false, + ExpectedAuthorizationHeaders: []string{"Bearer token"}, + ExpectedRecordedWarning: invalidTokenWithSpaceWarning, + }, "error bearer token": { AuthorizationHeaders: []string{"Bearer 123"}, TokenAuth: authenticator.TokenFunc(func(ctx context.Context, t string) (*authenticator.Response, bool, error) { @@ -197,7 +225,10 @@ func TestBearerToken(t *testing.T) { } for k, tc := range tests { - req, _ := http.NewRequest("GET", "/", nil) + dc := dummyRecorder{agent: "", text: ""} + ctx := genericapirequest.NewDefaultContext() + ctxWithRecorder := warning.WithWarningRecorder(ctx, &dc) + req, _ := http.NewRequestWithContext(ctxWithRecorder, "GET", "/", nil) for _, h := range tc.AuthorizationHeaders { req.Header.Add("Authorization", h) } @@ -216,6 +247,10 @@ func TestBearerToken(t *testing.T) { t.Errorf("%s: Expected username=%v, got %v", k, tc.ExpectedUserName, resp.User.GetName()) continue } + if len(tc.ExpectedRecordedWarning) > 0 && tc.ExpectedRecordedWarning != dc.getWarning() { + t.Errorf("%s: Expected recorded warning=%v, got %v", k, tc.ExpectedRecordedWarning, dc.getWarning()) + continue + } if !reflect.DeepEqual(req.Header["Authorization"], tc.ExpectedAuthorizationHeaders) { t.Errorf("%s: Expected headers=%#v, got %#v", k, tc.ExpectedAuthorizationHeaders, req.Header["Authorization"]) continue