mirror of
https://github.com/steveiliop56/tinyauth.git
synced 2025-12-31 12:32:29 +00:00
fix: allow any HTTP method for /api/auth/envoy (#551)
* feat: allow any HTTP method for /api/auth/envoy and restrict methods for non-envoy proxies * feat: add Allow header for invalid methods in proxyHandler
This commit is contained in:
@@ -43,8 +43,8 @@ func NewProxyController(config ProxyControllerConfig, router *gin.RouterGroup, a
|
||||
|
||||
func (controller *ProxyController) SetupRoutes() {
|
||||
proxyGroup := controller.router.Group("/auth")
|
||||
proxyGroup.GET("/:proxy", controller.proxyHandler)
|
||||
proxyGroup.POST("/:proxy", controller.proxyHandler)
|
||||
// There is a later check to control allowed methods per proxy
|
||||
proxyGroup.Any("/:proxy", controller.proxyHandler)
|
||||
}
|
||||
|
||||
func (controller *ProxyController) proxyHandler(c *gin.Context) {
|
||||
@@ -69,6 +69,19 @@ func (controller *ProxyController) proxyHandler(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// Only allow GET for non-envoy proxies.
|
||||
// Envoy uses the original client method for the external auth request
|
||||
// so we allow Any standard HTTP method for /api/auth/envoy
|
||||
if req.Proxy != "envoy" && c.Request.Method != http.MethodGet {
|
||||
log.Warn().Str("method", c.Request.Method).Msg("Invalid method for proxy")
|
||||
c.Header("Allow", "GET")
|
||||
c.JSON(405, gin.H{
|
||||
"status": 405,
|
||||
"message": "Method Not Allowed",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
isBrowser := strings.Contains(c.Request.Header.Get("Accept"), "text/html")
|
||||
|
||||
if isBrowser {
|
||||
|
||||
@@ -81,6 +81,14 @@ func TestProxyHandler(t *testing.T) {
|
||||
|
||||
assert.Equal(t, 400, recorder.Code)
|
||||
|
||||
// Test invalid method for non-envoy proxy
|
||||
recorder = httptest.NewRecorder()
|
||||
req = httptest.NewRequest("POST", "/api/auth/traefik", nil)
|
||||
router.ServeHTTP(recorder, req)
|
||||
|
||||
assert.Equal(t, 405, recorder.Code)
|
||||
assert.Equal(t, "GET", recorder.Header().Get("Allow"))
|
||||
|
||||
// Test logged out user (traefik/caddy)
|
||||
recorder = httptest.NewRecorder()
|
||||
req = httptest.NewRequest("GET", "/api/auth/traefik", nil)
|
||||
@@ -93,7 +101,7 @@ func TestProxyHandler(t *testing.T) {
|
||||
assert.Equal(t, 307, recorder.Code)
|
||||
assert.Equal(t, "http://localhost:8080/login?redirect_uri=https%3A%2F%2Fexample.com%2Fsomepath", recorder.Header().Get("Location"))
|
||||
|
||||
// Test logged out user (envoy)
|
||||
// Test logged out user (envoy - POST method)
|
||||
recorder = httptest.NewRecorder()
|
||||
req = httptest.NewRequest("POST", "/api/auth/envoy", nil)
|
||||
req.Header.Set("X-Forwarded-Proto", "https")
|
||||
@@ -105,6 +113,18 @@ func TestProxyHandler(t *testing.T) {
|
||||
assert.Equal(t, 307, recorder.Code)
|
||||
assert.Equal(t, "http://localhost:8080/login?redirect_uri=https%3A%2F%2Fexample.com%2Fsomepath", recorder.Header().Get("Location"))
|
||||
|
||||
// Test logged out user (envoy - DELETE method)
|
||||
recorder = httptest.NewRecorder()
|
||||
req = httptest.NewRequest("DELETE", "/api/auth/envoy", nil)
|
||||
req.Header.Set("X-Forwarded-Proto", "https")
|
||||
req.Header.Set("X-Forwarded-Host", "example.com")
|
||||
req.Header.Set("X-Forwarded-Uri", "/somepath")
|
||||
req.Header.Set("Accept", "text/html")
|
||||
router.ServeHTTP(recorder, req)
|
||||
|
||||
assert.Equal(t, 307, recorder.Code)
|
||||
assert.Equal(t, "http://localhost:8080/login?redirect_uri=https%3A%2F%2Fexample.com%2Fsomepath", recorder.Header().Get("Location"))
|
||||
|
||||
// Test logged out user (nginx)
|
||||
recorder = httptest.NewRecorder()
|
||||
req = httptest.NewRequest("GET", "/api/auth/nginx", nil)
|
||||
|
||||
Reference in New Issue
Block a user