Skip to content

Commit 46c7fdd

Browse files
Merge pull request #18378 from simo5/imprt
Automatic merge from submit-queue. Change Header used for impersonation scopes Fixes #18374
2 parents 4f13268 + 6ef9312 commit 46c7fdd

File tree

3 files changed

+24
-46
lines changed

3 files changed

+24
-46
lines changed

pkg/client/impersonatingclient/impersonate.go

+12-39
Original file line numberDiff line numberDiff line change
@@ -5,52 +5,23 @@ import (
55

66
"k8s.io/apimachinery/pkg/runtime/schema"
77
"k8s.io/apimachinery/pkg/types"
8-
utilnet "k8s.io/apimachinery/pkg/util/net"
98
"k8s.io/apiserver/pkg/authentication/user"
109
restclient "k8s.io/client-go/rest"
10+
"k8s.io/client-go/transport"
1111
"k8s.io/client-go/util/flowcontrol"
1212
kclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
13-
14-
authorizationapi "github.com/openshift/origin/pkg/authorization/apis/authorization"
15-
)
16-
17-
const (
18-
ImpersonateUserHeader = "Impersonate-User"
19-
ImpersonateGroupHeader = "Impersonate-Group"
20-
ImpersonateUserScopeHeader = "Impersonate-User-Scope"
2113
)
2214

23-
type impersonatingRoundTripper struct {
24-
user user.Info
25-
delegate http.RoundTripper
26-
}
27-
28-
// newImpersonatingRoundTripper will add headers to impersonate a user, including user, groups, and scopes
29-
func newImpersonatingRoundTripper(user user.Info, delegate http.RoundTripper) http.RoundTripper {
30-
return &impersonatingRoundTripper{user: user, delegate: delegate}
31-
}
32-
33-
func (rt *impersonatingRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
34-
req = utilnet.CloneRequest(req)
35-
req.Header.Del(ImpersonateUserHeader)
36-
req.Header.Del(ImpersonateGroupHeader)
37-
req.Header.Del(ImpersonateUserScopeHeader)
38-
39-
req.Header.Set(ImpersonateUserHeader, rt.user.GetName())
40-
for _, group := range rt.user.GetGroups() {
41-
req.Header.Add(ImpersonateGroupHeader, group)
42-
}
43-
for _, scope := range rt.user.GetExtra()[authorizationapi.ScopesKey] {
44-
req.Header.Add(ImpersonateUserScopeHeader, scope)
45-
}
46-
return rt.delegate.RoundTrip(req)
47-
}
48-
4915
// NewImpersonatingConfig wraps the config's transport to impersonate a user, including user, groups, and scopes
5016
func NewImpersonatingConfig(user user.Info, config restclient.Config) restclient.Config {
5117
oldWrapTransport := config.WrapTransport
5218
config.WrapTransport = func(rt http.RoundTripper) http.RoundTripper {
53-
return newImpersonatingRoundTripper(user, oldWrapTransport(rt))
19+
newConfig := transport.ImpersonationConfig{
20+
UserName: user.GetName(),
21+
Groups: user.GetGroups(),
22+
Extra: user.GetExtra(),
23+
}
24+
return transport.NewImpersonatingRoundTripper(newConfig, oldWrapTransport(rt))
5425
}
5526
return config
5627
}
@@ -73,9 +44,11 @@ func NewImpersonatingRESTClient(user user.Info, client restclient.Interface) res
7344

7445
// Verb does the impersonation per request by setting the proper headers
7546
func (c impersonatingRESTClient) impersonate(req *restclient.Request) *restclient.Request {
76-
req.SetHeader(ImpersonateUserHeader, c.user.GetName())
77-
req.SetHeader(ImpersonateGroupHeader, c.user.GetGroups()...)
78-
req.SetHeader(ImpersonateUserScopeHeader, c.user.GetExtra()[authorizationapi.ScopesKey]...)
47+
req.SetHeader(transport.ImpersonateUserHeader, c.user.GetName())
48+
req.SetHeader(transport.ImpersonateGroupHeader, c.user.GetGroups()...)
49+
for k, vv := range c.user.GetExtra() {
50+
req.SetHeader(transport.ImpersonateUserExtraHeaderPrefix+k, vv...)
51+
}
7952
return req
8053
}
8154

pkg/cmd/server/origin/handlers.go

+6-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import (
2323
coreapi "k8s.io/kubernetes/pkg/apis/core"
2424

2525
authorizationapi "github.com/openshift/origin/pkg/authorization/apis/authorization"
26-
"github.com/openshift/origin/pkg/client/impersonatingclient"
2726
configapi "github.com/openshift/origin/pkg/cmd/server/api"
2827
)
2928

@@ -155,10 +154,15 @@ func (c *MasterConfig) versionSkewFilter(handler http.Handler, contextMapper api
155154
})
156155
}
157156

157+
// legacyImpersonateUserScopeHeader is the header name older servers were using
158+
// just for scopes, so we need to translate it from clients that may still be
159+
// using it.
160+
const legacyImpersonateUserScopeHeader = "Impersonate-User-Scope"
161+
158162
// translateLegacyScopeImpersonation is a filter that will translates user scope impersonation for openshift into the equivalent kube headers.
159163
func translateLegacyScopeImpersonation(handler http.Handler) http.Handler {
160164
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
161-
for _, scope := range req.Header[impersonatingclient.ImpersonateUserScopeHeader] {
165+
for _, scope := range req.Header[legacyImpersonateUserScopeHeader] {
162166
req.Header[authenticationv1.ImpersonateUserExtraHeaderPrefix+authorizationapi.ScopesKey] =
163167
append(req.Header[authenticationv1.ImpersonateUserExtraHeaderPrefix+authorizationapi.ScopesKey], scope)
164168
}

test/integration/scopes_test.go

+6-5
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,17 @@ package integration
33
import (
44
"testing"
55

6+
authenticationv1 "k8s.io/api/authentication/v1"
67
kapierrors "k8s.io/apimachinery/pkg/api/errors"
78
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
89
apiserverserviceaccount "k8s.io/apiserver/pkg/authentication/serviceaccount"
910
"k8s.io/client-go/rest"
1011
kclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
1112

13+
authorizationapi "github.com/openshift/origin/pkg/authorization/apis/authorization"
1214
"github.com/openshift/origin/pkg/authorization/authorizer/scope"
1315
buildapi "github.com/openshift/origin/pkg/build/apis/build"
1416
buildclient "github.com/openshift/origin/pkg/build/generated/internalclientset"
15-
"github.com/openshift/origin/pkg/client/impersonatingclient"
1617
oauthapi "github.com/openshift/origin/pkg/oauth/apis/oauth"
1718
oauthclient "github.com/openshift/origin/pkg/oauth/generated/internalclientset/typed/oauth/internalversion"
1819
"github.com/openshift/origin/pkg/oauthserver/oauthserver"
@@ -105,17 +106,17 @@ func TestScopedImpersonation(t *testing.T) {
105106
}
106107

107108
err = clusterAdminBuildClient.Build().RESTClient().Get().
108-
SetHeader(impersonatingclient.ImpersonateUserHeader, "harold").
109-
SetHeader(impersonatingclient.ImpersonateUserScopeHeader, "user:info").
109+
SetHeader(authenticationv1.ImpersonateUserHeader, "harold").
110+
SetHeader(authenticationv1.ImpersonateUserExtraHeaderPrefix+authorizationapi.ScopesKey, "user:info").
110111
Namespace(projectName).Resource("builds").Name("name").Do().Into(&buildapi.Build{})
111112
if !kapierrors.IsForbidden(err) {
112113
t.Fatalf("unexpected error: %v", err)
113114
}
114115

115116
user := &userapi.User{}
116117
err = userclient.NewForConfigOrDie(clusterAdminClientConfig).RESTClient().Get().
117-
SetHeader(impersonatingclient.ImpersonateUserHeader, "harold").
118-
SetHeader(impersonatingclient.ImpersonateUserScopeHeader, "user:info").
118+
SetHeader(authenticationv1.ImpersonateUserHeader, "harold").
119+
SetHeader(authenticationv1.ImpersonateUserExtraHeaderPrefix+authorizationapi.ScopesKey, "user:info").
119120
Resource("users").Name("~").Do().Into(user)
120121
if err != nil {
121122
t.Fatalf("unexpected error: %v", err)

0 commit comments

Comments
 (0)