mirror of
https://github.com/lukaszraczylo/traefikoidc.git
synced 2026-10-12 04:04:26 +00:00
fix(middleware): forward configured headers on SSE/WebSocket bypass (#162)
The SSE and WebSocket bypass forwarded only X-Forwarded-User. It did not apply the configured headers. Backends that authenticate the proxy with a shared-secret header returned 401 on WebSocket upgrades. Version 0.8.x sent WebSocket upgrades through the normal flow, so this is a regression. The bypass now renders the header templates through applyHeaderTemplates, which forwardAuthorized also uses. Templates use the ID-token claims from the session cookie. If the session has no ID token, they use the access-token claims. The bypass now also rejects a session that the IdP logged out through back-channel or front-channel logout. Without this check, a logged-out cookie can open streams with the proxy secret attached. Add a yaegi check for the WebSocket case. Move tokenWithGroups to the shared JWT test helpers, as FIX-41 requires. Claude-Session: https://claude.ai/code/session_01G1d1n1BrHHHw8dBUkbiBPC
This commit is contained in:
@@ -2,8 +2,6 @@ package traefikoidc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
@@ -64,24 +62,6 @@ func TestIsRetryableError_HTTPErrorStatus(t *testing.T) {
|
||||
|
||||
// --- R118 fix C: bypass role gate must fall back to access-token claims ---
|
||||
|
||||
// tokenWithGroups builds a JWT whose signature segment is long enough to pass
|
||||
// the session chunk manager's format validation (>=10 chars) so the access
|
||||
// token round-trips through Set/GetAccessToken.
|
||||
func tokenWithGroups(t *testing.T, claims map[string]interface{}) string {
|
||||
t.Helper()
|
||||
hdr, _ := json.Marshal(map[string]string{"alg": "RS256", "typ": "JWT"})
|
||||
pl, _ := json.Marshal(claims)
|
||||
// Varied (non-repeating) signature bytes so the session chunk manager's
|
||||
// repeated-character heuristic does not reject it.
|
||||
sigBytes := make([]byte, 32)
|
||||
for i := range sigBytes {
|
||||
sigBytes[i] = byte(i + 1)
|
||||
}
|
||||
sig := base64.RawURLEncoding.EncodeToString(sigBytes)
|
||||
return base64.RawURLEncoding.EncodeToString(hdr) + "." +
|
||||
base64.RawURLEncoding.EncodeToString(pl) + "." + sig
|
||||
}
|
||||
|
||||
// TestApplyBypassUserHeaders_AccessTokenGroupFallback regresses R118: the
|
||||
// SSE/WebSocket bypass role gate read only the session's ID token, while the
|
||||
// main authorization path falls back to access-token claims when no ID token
|
||||
|
||||
Reference in New Issue
Block a user