Skip to content

Commit b44dc75

Browse files
authored
fix: return 307 redirects for envoy proxy instead of 401 (#782)
* fix: return 307 redirects for envoy proxy instead of 401 * tests: extend testing for non browser detection in all proxies
1 parent d25aaba commit b44dc75

2 files changed

Lines changed: 34 additions & 34 deletions

File tree

internal/controller/proxy_controller.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -323,12 +323,12 @@ func (controller *ProxyController) getHeader(c *gin.Context, header string) (str
323323
}
324324

325325
func (controller *ProxyController) useBrowserResponse(proxyCtx ProxyContext) bool {
326-
// If it's nginx or envoy we need non-browser response
327-
if proxyCtx.ProxyType == Nginx || proxyCtx.ProxyType == Envoy {
326+
// If it's nginx we need non-browser response
327+
if proxyCtx.ProxyType == Nginx {
328328
return false
329329
}
330330

331-
// For other proxies (traefik or caddy) we can check
331+
// For other proxies (traefik/caddy/envoy) we can check
332332
// the user agent to determine if it's a browser or not
333333
if proxyCtx.IsBrowser {
334334
return true

internal/controller/proxy_controller_test.go

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ func TestProxyController(t *testing.T) {
104104

105105
tests := []testCase{
106106
{
107-
description: "Default forward auth should be detected and used",
107+
description: "Default forward auth should be detected and used for traefik",
108108
middlewares: []gin.HandlerFunc{},
109109
run: func(t *testing.T, router *gin.Engine, recorder *httptest.ResponseRecorder) {
110110
req := httptest.NewRequest("GET", "/api/auth/traefik", nil)
@@ -126,6 +126,7 @@ func TestProxyController(t *testing.T) {
126126
run: func(t *testing.T, router *gin.Engine, recorder *httptest.ResponseRecorder) {
127127
req := httptest.NewRequest("GET", "/api/auth/nginx", nil)
128128
req.Header.Set("x-original-url", "https://test.example.com/")
129+
req.Header.Set("user-agent", browserUserAgent)
129130
router.ServeHTTP(recorder, req)
130131
assert.Equal(t, 401, recorder.Code)
131132
},
@@ -137,36 +138,33 @@ func TestProxyController(t *testing.T) {
137138
req := httptest.NewRequest("HEAD", "/api/auth/envoy?path=/hello", nil) // test a different method for envoy
138139
req.Host = "test.example.com"
139140
req.Header.Set("x-forwarded-proto", "https")
141+
req.Header.Set("user-agent", browserUserAgent)
140142
router.ServeHTTP(recorder, req)
141-
assert.Equal(t, 401, recorder.Code)
143+
assert.Equal(t, 307, recorder.Code)
144+
location := recorder.Header().Get("Location")
145+
assert.Contains(t, location, "https://tinyauth.example.com/login?redirect_uri=")
146+
assert.Contains(t, location, "https%3A%2F%2Ftest.example.com%2Fhello")
142147
},
143148
},
144149
{
145-
description: "Ensure forward auth fallback for nginx",
150+
description: "Forward auth with caddy should be detected and used",
146151
middlewares: []gin.HandlerFunc{},
147152
run: func(t *testing.T, router *gin.Engine, recorder *httptest.ResponseRecorder) {
148-
req := httptest.NewRequest("GET", "/api/auth/nginx", nil)
153+
req := httptest.NewRequest("GET", "/api/auth/caddy", nil)
149154
req.Header.Set("x-forwarded-host", "test.example.com")
150155
req.Header.Set("x-forwarded-proto", "https")
151156
req.Header.Set("x-forwarded-uri", "/")
157+
req.Header.Set("user-agent", browserUserAgent)
152158
router.ServeHTTP(recorder, req)
153-
assert.Equal(t, 401, recorder.Code)
154-
},
155-
},
156-
{
157-
description: "Ensure forward auth fallback for envoy",
158-
middlewares: []gin.HandlerFunc{},
159-
run: func(t *testing.T, router *gin.Engine, recorder *httptest.ResponseRecorder) {
160-
req := httptest.NewRequest("HEAD", "/api/auth/envoy?path=/hello", nil)
161-
req.Header.Set("x-forwarded-host", "test.example.com")
162-
req.Header.Set("x-forwarded-proto", "https")
163-
req.Header.Set("x-forwarded-uri", "/hello")
164-
router.ServeHTTP(recorder, req)
165-
assert.Equal(t, 401, recorder.Code)
159+
160+
assert.Equal(t, 307, recorder.Code)
161+
location := recorder.Header().Get("Location")
162+
assert.Contains(t, location, "https://tinyauth.example.com/login?redirect_uri=")
163+
assert.Contains(t, location, "https%3A%2F%2Ftest.example.com%2F")
166164
},
167165
},
168166
{
169-
description: "Ensure forward auth fallback for nginx with browser user agent",
167+
description: "Ensure forward auth fallback for nginx",
170168
middlewares: []gin.HandlerFunc{},
171169
run: func(t *testing.T, router *gin.Engine, recorder *httptest.ResponseRecorder) {
172170
req := httptest.NewRequest("GET", "/api/auth/nginx", nil)
@@ -179,20 +177,24 @@ func TestProxyController(t *testing.T) {
179177
},
180178
},
181179
{
182-
description: "Ensure forward auth fallback for envoy with browser user agent",
180+
description: "Ensure forward auth fallback for envoy",
183181
middlewares: []gin.HandlerFunc{},
184182
run: func(t *testing.T, router *gin.Engine, recorder *httptest.ResponseRecorder) {
185183
req := httptest.NewRequest("HEAD", "/api/auth/envoy?path=/hello", nil)
184+
req.Host = ""
186185
req.Header.Set("x-forwarded-host", "test.example.com")
187186
req.Header.Set("x-forwarded-proto", "https")
188187
req.Header.Set("x-forwarded-uri", "/hello")
189188
req.Header.Set("user-agent", browserUserAgent)
190189
router.ServeHTTP(recorder, req)
191-
assert.Equal(t, 401, recorder.Code)
190+
assert.Equal(t, 307, recorder.Code)
191+
location := recorder.Header().Get("Location")
192+
assert.Contains(t, location, "https://tinyauth.example.com/login?redirect_uri=")
193+
assert.Contains(t, location, "https%3A%2F%2Ftest.example.com%2Fhello")
192194
},
193195
},
194196
{
195-
description: "Ensure forward auth with is browser false returns json",
197+
description: "Ensure forward auth with non browser returns json for traefik",
196198
middlewares: []gin.HandlerFunc{},
197199
run: func(t *testing.T, router *gin.Engine, recorder *httptest.ResponseRecorder) {
198200
req := httptest.NewRequest("GET", "/api/auth/traefik", nil)
@@ -207,30 +209,28 @@ func TestProxyController(t *testing.T) {
207209
},
208210
},
209211
{
210-
description: "Ensure forward auth with caddy and browser user agent returns redirect",
212+
description: "Ensure forward auth with non browser returns json for caddy",
211213
middlewares: []gin.HandlerFunc{},
212214
run: func(t *testing.T, router *gin.Engine, recorder *httptest.ResponseRecorder) {
213-
req := httptest.NewRequest("GET", "/api/auth/traefik", nil)
215+
req := httptest.NewRequest("GET", "/api/auth/caddy", nil)
214216
req.Header.Set("x-forwarded-host", "test.example.com")
215217
req.Header.Set("x-forwarded-proto", "https")
216218
req.Header.Set("x-forwarded-uri", "/")
217-
req.Header.Set("user-agent", browserUserAgent)
218219
router.ServeHTTP(recorder, req)
219220

220-
assert.Equal(t, 307, recorder.Code)
221-
location := recorder.Header().Get("Location")
222-
assert.Contains(t, location, "https://tinyauth.example.com/login?redirect_uri=")
223-
assert.Contains(t, location, "https%3A%2F%2Ftest.example.com%2F")
221+
assert.Equal(t, 401, recorder.Code)
222+
assert.Contains(t, recorder.Body.String(), `"status":401`)
223+
assert.Contains(t, recorder.Body.String(), `"message":"Unauthorized"`)
224224
},
225225
},
226226
{
227-
description: "Ensure forward auth with caddy and non browser user agent returns json",
227+
description: "Ensure extauthz with envoy non browser returns json",
228228
middlewares: []gin.HandlerFunc{},
229229
run: func(t *testing.T, router *gin.Engine, recorder *httptest.ResponseRecorder) {
230-
req := httptest.NewRequest("GET", "/api/auth/traefik", nil)
230+
req := httptest.NewRequest("HEAD", "/api/auth/envoy?path=/hello", nil)
231231
req.Header.Set("x-forwarded-host", "test.example.com")
232232
req.Header.Set("x-forwarded-proto", "https")
233-
req.Header.Set("x-forwarded-uri", "/")
233+
req.Header.Set("x-forwarded-uri", "/hello")
234234
router.ServeHTTP(recorder, req)
235235

236236
assert.Equal(t, 401, recorder.Code)

0 commit comments

Comments
 (0)