client-go: add the UID to the auth-proxy roundtripper

Kubernetes-commit: 2cc0370169ea1fcf45429f9586e0ffd4ab32ed26
This commit is contained in:
Stanislav Láznička 2023-02-16 14:01:53 +01:00 committed by Kubernetes Publisher
parent 4fca7081f8
commit 9dd4d6ed78
2 changed files with 24 additions and 4 deletions

View File

@ -86,6 +86,7 @@ func DebugWrappers(rt http.RoundTripper) http.RoundTripper {
type authProxyRoundTripper struct {
username string
uid string
groups []string
extra map[string][]string
@ -98,15 +99,17 @@ var _ utilnet.RoundTripperWrapper = &authProxyRoundTripper{}
// authentication terminating proxy cases
// assuming you pull the user from the context:
// username is the user.Info.GetName() of the user
// uid is the user.Info.GetUID() of the user
// groups is the user.Info.GetGroups() of the user
// extra is the user.Info.GetExtra() of the user
// extra can contain any additional information that the authenticator
// thought was interesting, for example authorization scopes.
// In order to faithfully round-trip through an impersonation flow, these keys
// MUST be lowercase.
func NewAuthProxyRoundTripper(username string, groups []string, extra map[string][]string, rt http.RoundTripper) http.RoundTripper {
func NewAuthProxyRoundTripper(username, uid string, groups []string, extra map[string][]string, rt http.RoundTripper) http.RoundTripper {
return &authProxyRoundTripper{
username: username,
uid: uid,
groups: groups,
extra: extra,
rt: rt,
@ -115,14 +118,15 @@ func NewAuthProxyRoundTripper(username string, groups []string, extra map[string
func (rt *authProxyRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
req = utilnet.CloneRequest(req)
SetAuthProxyHeaders(req, rt.username, rt.groups, rt.extra)
SetAuthProxyHeaders(req, rt.username, rt.uid, rt.groups, rt.extra)
return rt.rt.RoundTrip(req)
}
// SetAuthProxyHeaders stomps the auth proxy header fields. It mutates its argument.
func SetAuthProxyHeaders(req *http.Request, username string, groups []string, extra map[string][]string) {
func SetAuthProxyHeaders(req *http.Request, username, uid string, groups []string, extra map[string][]string) {
req.Header.Del("X-Remote-User")
req.Header.Del("X-Remote-Uid")
req.Header.Del("X-Remote-Group")
for key := range req.Header {
if strings.HasPrefix(strings.ToLower(key), strings.ToLower("X-Remote-Extra-")) {
@ -131,6 +135,9 @@ func SetAuthProxyHeaders(req *http.Request, username string, groups []string, ex
}
req.Header.Set("X-Remote-User", username)
if len(uid) > 0 {
req.Header.Set("X-Remote-Uid", uid)
}
for _, group := range groups {
req.Header.Add("X-Remote-Group", group)
}

View File

@ -306,12 +306,14 @@ func TestImpersonationRoundTripper(t *testing.T) {
func TestAuthProxyRoundTripper(t *testing.T) {
for n, tc := range map[string]struct {
username string
uid string
groups []string
extra map[string][]string
expectedExtra map[string][]string
}{
"allfields": {
username: "user",
uid: "7db46926-e803-4337-9a29-f9c1fab7d34a",
groups: []string{"groupA", "groupB"},
extra: map[string][]string{
"one": {"alpha", "bravo"},
@ -324,6 +326,7 @@ func TestAuthProxyRoundTripper(t *testing.T) {
},
"escaped extra": {
username: "user",
uid: "7db46926-e803-4337-9a29-f9c1fab7d34a",
groups: []string{"groupA", "groupB"},
extra: map[string][]string{
"one": {"alpha", "bravo"},
@ -336,6 +339,7 @@ func TestAuthProxyRoundTripper(t *testing.T) {
},
"double escaped extra": {
username: "user",
uid: "7db46926-e803-4337-9a29-f9c1fab7d34a",
groups: []string{"groupA", "groupB"},
extra: map[string][]string{
"one": {"alpha", "bravo"},
@ -349,7 +353,7 @@ func TestAuthProxyRoundTripper(t *testing.T) {
} {
rt := &testRoundTripper{}
req := &http.Request{}
NewAuthProxyRoundTripper(tc.username, tc.groups, tc.extra, rt).RoundTrip(req)
_, _ = NewAuthProxyRoundTripper(tc.username, tc.uid, tc.groups, tc.extra, rt).RoundTrip(req)
if rt.Request == nil {
t.Errorf("%s: unexpected nil request: %v", n, rt)
continue
@ -368,6 +372,15 @@ func TestAuthProxyRoundTripper(t *testing.T) {
t.Errorf("%s expected %v, got %v", n, e, a)
continue
}
actualUID, ok := rt.Request.Header["X-Remote-Uid"]
if !ok {
t.Errorf("%s missing value", n)
continue
}
if e, a := []string{tc.uid}, actualUID; !reflect.DeepEqual(e, a) {
t.Errorf("%s expected %v, got %v", n, e, a)
continue
}
actualGroups, ok := rt.Request.Header["X-Remote-Group"]
if !ok {
t.Errorf("%s missing value", n)