@@ -1311,3 +1311,107 @@ func mustParseUrl(urlStr string) *url.URL {
13111311 }
13121312 return u
13131313}
1314+
1315+ func TestServeHTTPAudience (t * testing.T ) {
1316+ tests := []struct {
1317+ Name string
1318+ Fields []string
1319+ Aud string
1320+ Claims string
1321+ err string
1322+ nextCalled bool
1323+ }{
1324+ {
1325+ Name : "valid string audience" ,
1326+ Fields : []string {"aud" },
1327+ Aud : "my-api" ,
1328+ Claims : `{"aud": "my-api"}` ,
1329+ err : "" ,
1330+ nextCalled : true ,
1331+ },
1332+ {
1333+ Name : "valid array audience" ,
1334+ Fields : []string {"aud" },
1335+ Aud : "my-api" ,
1336+ Claims : `{"aud": ["other-api", "my-api"]}` ,
1337+ err : "" ,
1338+ nextCalled : true ,
1339+ },
1340+ {
1341+ Name : "invalid string audience" ,
1342+ Fields : []string {"aud" },
1343+ Aud : "my-api" ,
1344+ Claims : `{"aud": "other-api"}` ,
1345+ err : "token audience mismatch" ,
1346+ nextCalled : false ,
1347+ },
1348+ {
1349+ Name : "invalid array audience" ,
1350+ Fields : []string {"aud" },
1351+ Aud : "my-api" ,
1352+ Claims : `{"aud": ["other-api", "another-api"]}` ,
1353+ err : "token audience not found in list" ,
1354+ nextCalled : false ,
1355+ },
1356+ {
1357+ Name : "missing audience when required" ,
1358+ Fields : []string {"aud" },
1359+ Aud : "my-api" ,
1360+ Claims : `{}` ,
1361+ err : "payload missing required field aud" ,
1362+ nextCalled : false ,
1363+ },
1364+ {
1365+ Name : "audience not configured" ,
1366+ Fields : []string {"aud" },
1367+ Aud : "" ,
1368+ Claims : `{"aud": "my-api"}` ,
1369+ err : "" ,
1370+ nextCalled : true ,
1371+ },
1372+ {
1373+ Name : "invalid audience type" ,
1374+ Fields : []string {"aud" },
1375+ Aud : "my-api" ,
1376+ Claims : `{"aud": 123}` ,
1377+ err : "token audience has invalid type" ,
1378+ nextCalled : false ,
1379+ },
1380+ }
1381+
1382+ for _ , tt := range tests {
1383+ t .Run (tt .Name , func (t * testing.T ) {
1384+ ctx := context .Background ()
1385+ nextCalled := false
1386+ next := http .HandlerFunc (func (rw http.ResponseWriter , req * http.Request ) { nextCalled = true })
1387+
1388+ jwt , err := New (ctx , next , & Config {
1389+ PayloadFields : tt .Fields ,
1390+ Aud : tt .Aud ,
1391+ }, "test-traefik-jwt-plugin" )
1392+ if err != nil {
1393+ t .Fatal (err )
1394+ }
1395+
1396+ recorder := httptest .NewRecorder ()
1397+
1398+ req , err := http .NewRequestWithContext (ctx , http .MethodGet , "http://localhost" , nil )
1399+ if err != nil {
1400+ t .Fatal (err )
1401+ }
1402+
1403+ req .Header ["Authorization" ] = []string {"Bearer eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9." + base64 .RawURLEncoding .EncodeToString ([]byte (tt .Claims )) + ".JlX3gXGyClTBFciHhknWrjo7SKqyJ5iBO0n-3S2_I7cIgfaZAeRDJ3SQEbaPxVC7X8aqGCOM-pQOjZPKUJN8DMFrlHTOdqMs0TwQ2PRBmVAxXTSOZOoEhD4ZNCHohYoyfoDhJDP4Qye_FCqu6POJzg0Jcun4d3KW04QTiGxv2PkYqmB7nHxYuJdnqE3704hIS56pc_8q6AW0WIT0W-nIvwzaSbtBU9RgaC7ZpBD2LiNE265UBIFraMDF8IAFw9itZSUCTKg1Q-q27NwwBZNGYStMdIBDor2Bsq5ge51EkWajzZ7ALisVp-bskzUsqUf77ejqX_CBAqkNdH1Zebn93A" }
1404+
1405+ jwt .ServeHTTP (recorder , req )
1406+
1407+ if tt .nextCalled != nextCalled {
1408+ t .Fatalf ("Expected next.ServeHTTP called: %v, got: %v" , tt .nextCalled , nextCalled )
1409+ }
1410+ if tt .err != "" {
1411+ if strings .TrimSpace (recorder .Body .String ()) != tt .err {
1412+ t .Fatalf ("Expected error: %s, got: %s" , tt .err , recorder .Body .String ())
1413+ }
1414+ }
1415+ })
1416+ }
1417+ }
0 commit comments