diff --git a/docs/admin/authentication.md b/docs/admin/authentication.md index c6039a4f0e5..399da325ab0 100644 --- a/docs/admin/authentication.md +++ b/docs/admin/authentication.md @@ -46,7 +46,8 @@ to apiserver. Currently, tokens last indefinitely, and the token list cannot be changed without restarting apiserver. The token file format is implemented in `plugin/pkg/auth/authenticator/token/tokenfile/...` -and is a csv file with 3 columns: token, user name, user uid. +and is a csv file with a minimum of 3 columns: token, user name, user uid, followed by +optional group names. When using token authentication from an http client the apiserver expects an `Authorization` header with a value of `Bearer SOMETOKEN`. diff --git a/plugin/pkg/auth/authenticator/token/tokenfile/tokenfile.go b/plugin/pkg/auth/authenticator/token/tokenfile/tokenfile.go index e502bfc414b..ad725860458 100644 --- a/plugin/pkg/auth/authenticator/token/tokenfile/tokenfile.go +++ b/plugin/pkg/auth/authenticator/token/tokenfile/tokenfile.go @@ -40,6 +40,7 @@ func NewCSV(path string) (*TokenAuthenticator, error) { tokens := make(map[string]*user.DefaultInfo) reader := csv.NewReader(file) + reader.FieldsPerRecord = -1 for { record, err := reader.Read() if err == io.EOF { @@ -56,6 +57,10 @@ func NewCSV(path string) (*TokenAuthenticator, error) { UID: record[2], } tokens[record[0]] = obj + + if len(record) > 3 { + obj.Groups = record[3:] + } } return &TokenAuthenticator{ diff --git a/plugin/pkg/auth/authenticator/token/tokenfile/tokenfile_test.go b/plugin/pkg/auth/authenticator/token/tokenfile/tokenfile_test.go index 4638577eefa..31f3e620dfd 100644 --- a/plugin/pkg/auth/authenticator/token/tokenfile/tokenfile_test.go +++ b/plugin/pkg/auth/authenticator/token/tokenfile/tokenfile_test.go @@ -29,6 +29,8 @@ func TestTokenFile(t *testing.T) { auth, err := newWithContents(t, ` token1,user1,uid1 token2,user2,uid2 +token3,user3,uid3,group1,group2 +token4,user4,uid4,group2 `) if err != nil { t.Fatalf("unable to read tokenfile: %v", err) @@ -52,9 +54,19 @@ token2,user2,uid2 }, { Token: "token3", + User: &user.DefaultInfo{Name: "user3", UID: "uid3", Groups: []string{"group1", "group2"}}, + Ok: true, }, { Token: "token4", + User: &user.DefaultInfo{Name: "user4", UID: "uid4", Groups: []string{"group2"}}, + Ok: true, + }, + { + Token: "token5", + }, + { + Token: "token6", }, } for i, testCase := range testCases { @@ -66,6 +78,7 @@ token2,user2,uid2 } else if !reflect.DeepEqual(testCase.User, user) { t.Errorf("%d: expected user %#v, got %#v", i, testCase.User, user) } + if testCase.Ok != ok { t.Errorf("%d: expected auth %v, got %v", i, testCase.Ok, ok) }