|
1 | 1 | package headers
|
2 | 2 |
|
3 |
| -import "net/http" |
| 3 | +import ( |
| 4 | + "net/http" |
| 5 | + |
| 6 | + osinv1 "github.com/openshift/api/osin/v1" |
| 7 | +) |
4 | 8 |
|
5 | 9 | const (
|
6 |
| - authzHeader = "Authorization" |
7 |
| - copyAuthzHeader = "oauth.openshift.io:" + authzHeader // will never conflict because : is not a valid header key |
| 10 | + authzHeader = "Authorization" |
| 11 | + headerCopyPrefix = "oauth.openshift.io:" // will never conflict because : is not a valid header key |
8 | 12 | )
|
9 | 13 |
|
10 |
| -func WithPreserveAuthorizationHeader(handler http.Handler) http.Handler { |
| 14 | +func preservedHeaders(oauthConfig *osinv1.OAuthConfig) []string { |
| 15 | + // compile a list of headers that should be preserved lest any handler in the kube chain deletes them |
| 16 | + // so that WithOAuth can use them even after WithAuthentication deletes them |
| 17 | + // WithOAuth sees users' passwords and can mint tokens so this is not really an issue |
| 18 | + preservedHeaders := make([]string, 0) |
| 19 | + for _, identityProvider := range oauthConfig.IdentityProviders { |
| 20 | + switch provider := identityProvider.Provider.Object.(type) { |
| 21 | + case *osinv1.RequestHeaderIdentityProvider: |
| 22 | + preservedHeaders = append(preservedHeaders, provider.Headers...) |
| 23 | + preservedHeaders = append(preservedHeaders, provider.PreferredUsernameHeaders...) |
| 24 | + preservedHeaders = append(preservedHeaders, provider.NameHeaders...) |
| 25 | + preservedHeaders = append(preservedHeaders, provider.EmailHeaders...) |
| 26 | + } |
| 27 | + } |
| 28 | + |
| 29 | + return preservedHeaders |
| 30 | +} |
| 31 | + |
| 32 | +func WithPreserveOAuthHeaders(handler http.Handler, oauthConfig osinv1.OAuthConfig) http.Handler { |
| 33 | + headers := append(preservedHeaders(&oauthConfig), authzHeader) |
11 | 34 | return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
12 |
| - if vv, ok := r.Header[authzHeader]; ok { |
13 |
| - r.Header[copyAuthzHeader] = vv // capture the values before they are deleted |
| 35 | + for _, header := range headers { |
| 36 | + if vv, ok := r.Header[header]; ok { |
| 37 | + headerCopy := headerCopyPrefix + header |
| 38 | + r.Header[headerCopy] = vv // capture the values before they are deleted |
| 39 | + } |
14 | 40 | }
|
15 | 41 |
|
16 | 42 | handler.ServeHTTP(w, r)
|
17 | 43 | })
|
18 | 44 | }
|
19 | 45 |
|
20 |
| -func WithRestoreAuthorizationHeader(handler http.Handler) http.Handler { |
| 46 | +func WithRestoreOAuthHeaders(handler http.Handler, oauthConfig osinv1.OAuthConfig) http.Handler { |
| 47 | + headers := append(preservedHeaders(&oauthConfig), authzHeader) |
21 | 48 | return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
22 |
| - if vv, ok := r.Header[copyAuthzHeader]; ok { |
23 |
| - r.Header[authzHeader] = vv // add them back afterwards for use in OAuth flows |
24 |
| - delete(r.Header, copyAuthzHeader) |
| 49 | + for _, header := range headers { |
| 50 | + headerCopy := headerCopyPrefix + header |
| 51 | + if vv, ok := r.Header[headerCopy]; ok { |
| 52 | + r.Header[header] = vv // add them back afterwards for use in OAuth flows |
| 53 | + delete(r.Header, headerCopy) |
| 54 | + } |
25 | 55 | }
|
26 | 56 |
|
27 | 57 | handler.ServeHTTP(w, r)
|
|
0 commit comments