@@ -390,6 +390,121 @@ func TestProxyRouter_AuthorizationHeaderDefaultBehavior(t *testing.T) {
390390 })
391391}
392392
393+ func TestProxyRouter_HeaderMappingStripsClientHeaders (t * testing.T ) {
394+ privateKey , publicKey , err := generateRSAKeyPair ()
395+ require .NoError (t , err )
396+
397+ cases := []struct {
398+ name string
399+ headerMapping map [string ]string
400+ headerMappingBase string
401+ claims jwt.MapClaims
402+ clientHeaders map [string ]string
403+ expectedHeaders map [string ]string
404+ missingHeaders []string
405+ }{
406+ {
407+ name : "claim missing strips client header" ,
408+ headerMapping : map [string ]string {"/groups" : "X-Forwarded-Groups" },
409+ headerMappingBase : "/userinfo" ,
410+ claims : jwt.MapClaims {
411+ "sub" : "test-user" ,
412+ "userinfo" :
map [
string ]
any {
"email" :
"[email protected] " },
413+ "exp" : time .Now ().Add (time .Hour ).Unix (),
414+ "iat" : time .Now ().Unix (),
415+ },
416+ clientHeaders : map [string ]string {"X-Forwarded-Groups" : "admin" },
417+ missingHeaders : []string {"X-Forwarded-Groups" },
418+ },
419+ {
420+ name : "claim present overwrites client header" ,
421+ headerMapping : map [string ]string {"/email" : "X-Forwarded-Email" },
422+ headerMappingBase : "/userinfo" ,
423+ claims : jwt.MapClaims {
424+ "sub" : "test-user" ,
425+ "userinfo" :
map [
string ]
any {
"email" :
"[email protected] " },
426+ "exp" : time .Now ().Add (time .Hour ).Unix (),
427+ "iat" : time .Now ().Unix (),
428+ },
429+ clientHeaders :
map [
string ]
string {
"X-Forwarded-Email" :
"[email protected] " },
430+ expectedHeaders : map [string ]string {
431+ "X-Forwarded-Email" :
"[email protected] " ,
432+ },
433+ },
434+ {
435+ name : "base path absent strips client header" ,
436+ headerMapping : map [string ]string {"/email" : "X-Forwarded-Email" },
437+ headerMappingBase : "/userinfo" ,
438+ claims : jwt.MapClaims {
439+ "sub" : "test-user" ,
440+ "exp" : time .Now ().Add (time .Hour ).Unix (),
441+ "iat" : time .Now ().Unix (),
442+ },
443+ clientHeaders :
map [
string ]
string {
"X-Forwarded-Email" :
"[email protected] " },
444+ missingHeaders : []string {"X-Forwarded-Email" },
445+ },
446+ {
447+ name : "mixed mappings only set claims that exist" ,
448+ headerMapping : map [string ]string {"/email" : "X-Forwarded-Email" , "/groups" : "X-Forwarded-Groups" },
449+ headerMappingBase : "/" ,
450+ claims : jwt.MapClaims {
451+ "sub" : "test-user" ,
452+ 453+ "exp" : time .Now ().Add (time .Hour ).Unix (),
454+ "iat" : time .Now ().Unix (),
455+ },
456+ clientHeaders : map [string ]string {
457+ "X-Forwarded-Email" :
"[email protected] " ,
458+ "X-Forwarded-Groups" : "admin" ,
459+ },
460+ expectedHeaders : map [string ]string {
461+ "X-Forwarded-Email" :
"[email protected] " ,
462+ },
463+ missingHeaders : []string {"X-Forwarded-Groups" },
464+ },
465+ }
466+
467+ for _ , tt := range cases {
468+ t .Run (tt .name , func (t * testing.T ) {
469+ receivedHeaders := http.Header {}
470+ proxyHandler := http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
471+ for k , v := range r .Header {
472+ receivedHeaders [k ] = v
473+ }
474+ w .WriteHeader (http .StatusOK )
475+ })
476+
477+ proxyRouter , err := NewProxyRouter ("https://example.com" , proxyHandler , publicKey , http.Header {}, false , false , tt .headerMapping , tt .headerMappingBase )
478+ require .NoError (t , err )
479+
480+ gin .SetMode (gin .TestMode )
481+ router := gin .New ()
482+ proxyRouter .SetupRoutes (router )
483+
484+ token , err := createJWT (privateKey , tt .claims )
485+ require .NoError (t , err )
486+
487+ req , err := http .NewRequest ("GET" , "/test" , nil )
488+ require .NoError (t , err )
489+ req .Header .Set ("Authorization" , "Bearer " + token )
490+ for k , v := range tt .clientHeaders {
491+ req .Header .Set (k , v )
492+ }
493+
494+ w := httptest .NewRecorder ()
495+ router .ServeHTTP (w , req )
496+
497+ assert .Equal (t , http .StatusOK , w .Code )
498+ for header , expected := range tt .expectedHeaders {
499+ assert .Equal (t , expected , receivedHeaders .Get (header ), "header %s mismatch" , header )
500+ }
501+ for _ , header := range tt .missingHeaders {
502+ assert .Empty (t , receivedHeaders .Get (header ), "header %s should be stripped" , header )
503+ }
504+ })
505+ }
506+ }
507+
393508func TestProxyRouter_ProtectedResourceTrailingSlash (t * testing.T ) {
394509 _ , publicKey , err := generateRSAKeyPair ()
395510 require .NoError (t , err )
0 commit comments