Merge pull request #82208 from yutedz/filter-audience

Verify the response audience matches one of apiAuds
This commit is contained in:
Kubernetes Prow Robot 2019-09-13 08:14:30 -07:00 committed by GitHub
commit b1dfd2491a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 86 additions and 6 deletions

View File

@ -96,8 +96,11 @@ func WithAuthentication(handler http.Handler, auth authenticator.Request, failed
return
}
// TODO(mikedanese): verify the response audience matches one of apiAuds if
// non-empty
if len(apiAuds) > 0 && len(resp.Audiences) > 0 && len(authenticator.Audiences(apiAuds).Intersect(resp.Audiences)) == 0 {
klog.Errorf("Unable to match the audience: %v , accepted: %v", resp.Audiences, apiAuds)
failed.ServeHTTP(w, req)
return
}
// authorization header is not required anymore in case of a successful authentication.
req.Header.Del("Authorization")

View File

@ -18,15 +18,92 @@ package filters
import (
"errors"
"net/http"
"net/http/httptest"
"testing"
"github.com/stretchr/testify/assert"
"k8s.io/apiserver/pkg/authentication/authenticator"
"k8s.io/apiserver/pkg/authentication/user"
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
"net/http"
"net/http/httptest"
"testing"
)
func TestAuthenticateRequestWithAud(t *testing.T) {
success, failed := 0, 0
testcases := []struct {
name string
apiAuds []string
respAuds []string
expectSuccess bool
}{
{
name: "no api audience and no audience in response",
apiAuds: nil,
respAuds: nil,
expectSuccess: true,
},
{
name: "audience in response",
apiAuds: nil,
respAuds: []string{"other"},
expectSuccess: true,
},
{
name: "with api audience",
apiAuds: authenticator.Audiences([]string{"other"}),
respAuds: nil,
expectSuccess: true,
},
{
name: "api audience matching response audience",
apiAuds: authenticator.Audiences([]string{"other"}),
respAuds: []string{"other"},
expectSuccess: true,
},
{
name: "api audience non-matching response audience",
apiAuds: authenticator.Audiences([]string{"other"}),
respAuds: []string{"some"},
expectSuccess: false,
},
}
for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
success, failed = 0, 0
auth := WithAuthentication(
http.HandlerFunc(func(_ http.ResponseWriter, req *http.Request) {
if tc.expectSuccess {
success = 1
} else {
t.Errorf("unexpected call to handler")
}
}),
authenticator.RequestFunc(func(req *http.Request) (*authenticator.Response, bool, error) {
if req.Header.Get("Authorization") == "Something" {
return &authenticator.Response{User: &user.DefaultInfo{Name: "user"}, Audiences: authenticator.Audiences(tc.respAuds)}, true, nil
}
return nil, false, errors.New("Authorization header is missing.")
}),
http.HandlerFunc(func(_ http.ResponseWriter, _ *http.Request) {
if tc.expectSuccess {
t.Errorf("unexpected call to failed")
} else {
failed = 1
}
}),
tc.apiAuds,
)
auth.ServeHTTP(httptest.NewRecorder(), &http.Request{Header: map[string][]string{"Authorization": {"Something"}}})
if tc.expectSuccess {
assert.Equal(t, 1, success)
assert.Equal(t, 0, failed)
} else {
assert.Equal(t, 0, success)
assert.Equal(t, 1, failed)
}
})
}
}
func TestAuthenticateRequest(t *testing.T) {
success := make(chan struct{})
auth := WithAuthentication(