@@ -1,6 +1,7 @@
1package options
1package options
@@ -15,6 +16,9 @@ type LegacyOptions struct {
15 // Legacy options related to upstream servers
16 // Legacy options related to upstream servers
16 LegacyUpstreams LegacyUpstreams `cfg:",squash"`
17 LegacyUpstreams LegacyUpstreams `cfg:",squash"`
19+ // Legacy options for injecting request/response headers
20+ LegacyHeaders LegacyHeaders `cfg:",squash"`
18 Options Options `cfg:",squash"`
22 Options Options `cfg:",squash"`
@@ -26,6 +30,11 @@ func NewLegacyOptions() *LegacyOptions {
26 FlushInterval: time.Duration(1) * time.Second,
30 FlushInterval: time.Duration(1) * time.Second,
33+ LegacyHeaders: LegacyHeaders{
35+ PassUserHeaders: true,
29 Options: *NewOptions(),
38 Options: *NewOptions(),
@@ -119,3 +128,250 @@ func (l *LegacyUpstreams) convert() (Upstreams, error) {
120 return upstreams, nil
129 return upstreams, nil
132+type LegacyHeaders struct {
133+ PassBasicAuth bool `flag:"pass-basic-auth" cfg:"pass_basic_auth"`
134+ PassAccessToken bool `flag:"pass-access-token" cfg:"pass_access_token"`
135+ PassUserHeaders bool `flag:"pass-user-headers" cfg:"pass_user_headers"`
136+ PassAuthorization bool `flag:"pass-authorization-header" cfg:"pass_authorization_header"`
138+ SetBasicAuth bool `flag:"set-basic-auth" cfg:"set_basic_auth"`
139+ SetXAuthRequest bool `flag:"set-xauthrequest" cfg:"set_xauthrequest"`
140+ SetAuthorization bool `flag:"set-authorization-header" cfg:"set_authorization_header"`
142+ PreferEmailToUser bool `flag:"prefer-email-to-user" cfg:"prefer_email_to_user"`
143+ BasicAuthPassword string `flag:"basic-auth-password" cfg:"basic_auth_password"`
144+ SkipAuthStripHeaders bool `flag:"skip-auth-strip-headers" cfg:"skip_auth_strip_headers"`
147+func legacyHeadersFlagSet() *pflag.FlagSet {
148+ flagSet := pflag.NewFlagSet("headers", pflag.ExitOnError)
150+ flagSet.Bool("pass-basic-auth", true, "pass HTTP Basic Auth, X-Forwarded-User and X-Forwarded-Email information to upstream")
151+ flagSet.Bool("pass-access-token", false, "pass OAuth access_token to upstream via X-Forwarded-Access-Token header")
152+ flagSet.Bool("pass-user-headers", true, "pass X-Forwarded-User and X-Forwarded-Email information to upstream")
153+ flagSet.Bool("pass-authorization-header", false, "pass the Authorization Header to upstream")
155+ flagSet.Bool("set-basic-auth", false, "set HTTP Basic Auth information in response (useful in Nginx auth_request mode)")
156+ flagSet.Bool("set-xauthrequest", false, "set X-Auth-Request-User and X-Auth-Request-Email response headers (useful in Nginx auth_request mode)")
157+ flagSet.Bool("set-authorization-header", false, "set Authorization response headers (useful in Nginx auth_request mode)")
159+ flagSet.Bool("prefer-email-to-user", false, "Prefer to use the Email address as the Username when passing information to upstream. Will only use Username if Email is unavailable, eg. htaccess authentication. Used in conjunction with -pass-basic-auth and -pass-user-headers")
160+ flagSet.String("basic-auth-password", "", "the password to set when passing the HTTP Basic Auth header")
161+ flagSet.Bool("skip-auth-strip-headers", false, "strips X-Forwarded-* style authentication headers & Authorization header if they would be set by oauth2-proxy for request paths in --skip-auth-regex")
166+// convert takes the legacy request/response headers and converts them to
167+// the new format for InjectRequestHeaders and InjectResponseHeaders
168+func (l *LegacyHeaders) convert() ([]Header, []Header) {
169+ return l.getRequestHeaders(), l.getResponseHeaders()
172+func (l *LegacyHeaders) getRequestHeaders() []Header {
173+ requestHeaders := []Header{}
175+ if l.PassBasicAuth {
176+ requestHeaders = append(requestHeaders, getBasicAuthHeader(l.PreferEmailToUser, l.BasicAuthPassword))
179+ // In the old implementation, PassUserHeaders is a subset of PassBasicAuth
180+ if l.PassBasicAuth || l.PassUserHeaders {
181+ requestHeaders = append(requestHeaders, getPassUserHeaders(l.PreferEmailToUser)...)
182+ requestHeaders = append(requestHeaders, getPreferredUsernameHeader())
185+ if l.PassAccessToken {
186+ requestHeaders = append(requestHeaders, getPassAccessTokenHeader())
189+ if l.PassAuthorization {
190+ requestHeaders = append(requestHeaders, getAuthorizationHeader())
193+ return requestHeaders
196+func (l *LegacyHeaders) getResponseHeaders() []Header {
197+ responseHeaders := []Header{}
199+ if l.SetXAuthRequest {
200+ responseHeaders = append(responseHeaders, getXAuthRequestHeaders(l.PassAccessToken)...)
204+ responseHeaders = append(responseHeaders, getBasicAuthHeader(l.PreferEmailToUser, l.BasicAuthPassword))
207+ if l.SetAuthorization {
208+ responseHeaders = append(responseHeaders, getAuthorizationHeader())
211+ return responseHeaders
214+func getBasicAuthHeader(preferEmailToUser bool, basicAuthPassword string) Header {
216+ if preferEmailToUser {
221+ Name: "Authorization",
222+ Values: []HeaderValue{
224+ ClaimSource: &ClaimSource{
226+ BasicAuthPassword: &SecretSource{
227+ Value: []byte(base64.StdEncoding.EncodeToString([]byte(basicAuthPassword))),
235+func getPassUserHeaders(preferEmailToUser bool) []Header {
236+ headers := []Header{
238+ Name: "X-Forwarded-Groups",
239+ Values: []HeaderValue{
241+ ClaimSource: &ClaimSource{
249+ if preferEmailToUser {
250+ return append(headers,
252+ Name: "X-Forwarded-User",
253+ Values: []HeaderValue{
255+ ClaimSource: &ClaimSource{
263+ return append(headers,
265+ Name: "X-Forwarded-User",
266+ Values: []HeaderValue{
268+ ClaimSource: &ClaimSource{
275+ Name: "X-Forwarded-Email",
276+ Values: []HeaderValue{
278+ ClaimSource: &ClaimSource{
288+func getPassAccessTokenHeader() Header {
290+ Name: "X-Forwarded-Access-Token",
291+ Values: []HeaderValue{
293+ ClaimSource: &ClaimSource{
294+ Claim: "access_token",
301+func getAuthorizationHeader() Header {
303+ Name: "Authorization",
304+ Values: []HeaderValue{
306+ ClaimSource: &ClaimSource{
315+func getPreferredUsernameHeader() Header {
317+ Name: "X-Forwarded-Preferred-Username",
318+ Values: []HeaderValue{
320+ ClaimSource: &ClaimSource{
321+ Claim: "preferred_username",
328+func getXAuthRequestHeaders(passAccessToken bool) []Header {
329+ headers := []Header{
331+ Name: "X-Auth-Request-User",
332+ Values: []HeaderValue{
334+ ClaimSource: &ClaimSource{
341+ Name: "X-Auth-Request-Email",
342+ Values: []HeaderValue{
344+ ClaimSource: &ClaimSource{
350+ getPreferredUsernameHeader(),
352+ Name: "X-Auth-Request-Groups",
353+ Values: []HeaderValue{
355+ ClaimSource: &ClaimSource{
363+ if passAccessToken {
364+ headers = append(headers, Header{
365+ Name: "X-Auth-Request-Access-Token",
366+ Values: []HeaderValue{
368+ ClaimSource: &ClaimSource{
369+ Claim: "access_token",