@@ -1311,3 +1311,107 @@ func mustParseUrl(urlStr string) *url.URL {
1311
1311
}
1312
1312
return u
1313
1313
}
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