@@ -284,7 +284,7 @@ func TestHealthCheck(t *testing.T) {
284
284
})
285
285
})
286
286
// Health exposed even when require Authorization
287
- testCaseWithContext (t , & httpContext {StaticConfig : & config.StaticConfig {RequireOAuth : true }}, func (ctx * httpContext ) {
287
+ testCaseWithContext (t , & httpContext {StaticConfig : & config.StaticConfig {RequireOAuth : true , ValidateToken : true }}, func (ctx * httpContext ) {
288
288
resp , err := http .Get (fmt .Sprintf ("http://%s/healthz" , ctx .HttpAddress ))
289
289
if err != nil {
290
290
t .Fatalf ("Failed to get health check endpoint with OAuth: %v" , err )
@@ -305,7 +305,7 @@ func TestWellKnownReverseProxy(t *testing.T) {
305
305
".well-known/openid-configuration" ,
306
306
}
307
307
// With No Authorization URL configured
308
- testCaseWithContext (t , & httpContext {StaticConfig : & config.StaticConfig {RequireOAuth : true }}, func (ctx * httpContext ) {
308
+ testCaseWithContext (t , & httpContext {StaticConfig : & config.StaticConfig {RequireOAuth : true , ValidateToken : true }}, func (ctx * httpContext ) {
309
309
for _ , path := range cases {
310
310
resp , err := http .Get (fmt .Sprintf ("http://%s/%s" , ctx .HttpAddress , path ))
311
311
t .Cleanup (func () { _ = resp .Body .Close () })
@@ -329,7 +329,7 @@ func TestWellKnownReverseProxy(t *testing.T) {
329
329
_ , _ = w .Write ([]byte (`{"issuer": "https://example.com","scopes_supported":["mcp-server"]}` ))
330
330
}))
331
331
t .Cleanup (testServer .Close )
332
- testCaseWithContext (t , & httpContext {StaticConfig : & config.StaticConfig {AuthorizationURL : testServer .URL , RequireOAuth : true }}, func (ctx * httpContext ) {
332
+ testCaseWithContext (t , & httpContext {StaticConfig : & config.StaticConfig {AuthorizationURL : testServer .URL , RequireOAuth : true , ValidateToken : true }}, func (ctx * httpContext ) {
333
333
for _ , path := range cases {
334
334
resp , err := http .Get (fmt .Sprintf ("http://%s/%s" , ctx .HttpAddress , path ))
335
335
t .Cleanup (func () { _ = resp .Body .Close () })
@@ -377,7 +377,7 @@ func TestMiddlewareLogging(t *testing.T) {
377
377
378
378
func TestAuthorizationUnauthorized (t * testing.T ) {
379
379
// Missing Authorization header
380
- testCaseWithContext (t , & httpContext {StaticConfig : & config.StaticConfig {RequireOAuth : true }}, func (ctx * httpContext ) {
380
+ testCaseWithContext (t , & httpContext {StaticConfig : & config.StaticConfig {RequireOAuth : true , ValidateToken : true }}, func (ctx * httpContext ) {
381
381
resp , err := http .Get (fmt .Sprintf ("http://%s/mcp" , ctx .HttpAddress ))
382
382
if err != nil {
383
383
t .Fatalf ("Failed to get protected endpoint: %v" , err )
@@ -402,7 +402,7 @@ func TestAuthorizationUnauthorized(t *testing.T) {
402
402
})
403
403
})
404
404
// Authorization header without Bearer prefix
405
- testCaseWithContext (t , & httpContext {StaticConfig : & config.StaticConfig {RequireOAuth : true }}, func (ctx * httpContext ) {
405
+ testCaseWithContext (t , & httpContext {StaticConfig : & config.StaticConfig {RequireOAuth : true , ValidateToken : true }}, func (ctx * httpContext ) {
406
406
req , err := http .NewRequest ("GET" , fmt .Sprintf ("http://%s/mcp" , ctx .HttpAddress ), nil )
407
407
if err != nil {
408
408
t .Fatalf ("Failed to create request: %v" , err )
@@ -427,7 +427,7 @@ func TestAuthorizationUnauthorized(t *testing.T) {
427
427
})
428
428
})
429
429
// Invalid Authorization header
430
- testCaseWithContext (t , & httpContext {StaticConfig : & config.StaticConfig {RequireOAuth : true }}, func (ctx * httpContext ) {
430
+ testCaseWithContext (t , & httpContext {StaticConfig : & config.StaticConfig {RequireOAuth : true , ValidateToken : true }}, func (ctx * httpContext ) {
431
431
req , err := http .NewRequest ("GET" , fmt .Sprintf ("http://%s/mcp" , ctx .HttpAddress ), nil )
432
432
if err != nil {
433
433
t .Fatalf ("Failed to create request: %v" , err )
@@ -458,7 +458,7 @@ func TestAuthorizationUnauthorized(t *testing.T) {
458
458
})
459
459
})
460
460
// Expired Authorization Bearer token
461
- testCaseWithContext (t , & httpContext {StaticConfig : & config.StaticConfig {RequireOAuth : true }}, func (ctx * httpContext ) {
461
+ testCaseWithContext (t , & httpContext {StaticConfig : & config.StaticConfig {RequireOAuth : true , ValidateToken : true }}, func (ctx * httpContext ) {
462
462
req , err := http .NewRequest ("GET" , fmt .Sprintf ("http://%s/mcp" , ctx .HttpAddress ), nil )
463
463
if err != nil {
464
464
t .Fatalf ("Failed to create request: %v" , err )
@@ -489,7 +489,7 @@ func TestAuthorizationUnauthorized(t *testing.T) {
489
489
})
490
490
})
491
491
// Invalid audience claim Bearer token
492
- testCaseWithContext (t , & httpContext {StaticConfig : & config.StaticConfig {RequireOAuth : true , OAuthAudience : "expected-audience" }}, func (ctx * httpContext ) {
492
+ testCaseWithContext (t , & httpContext {StaticConfig : & config.StaticConfig {RequireOAuth : true , OAuthAudience : "expected-audience" , ValidateToken : true }}, func (ctx * httpContext ) {
493
493
req , err := http .NewRequest ("GET" , fmt .Sprintf ("http://%s/mcp" , ctx .HttpAddress ), nil )
494
494
if err != nil {
495
495
t .Fatalf ("Failed to create request: %v" , err )
@@ -522,7 +522,7 @@ func TestAuthorizationUnauthorized(t *testing.T) {
522
522
// Failed OIDC validation
523
523
key , oidcProvider , httpServer := NewOidcTestServer (t )
524
524
t .Cleanup (httpServer .Close )
525
- testCaseWithContext (t , & httpContext {StaticConfig : & config.StaticConfig {RequireOAuth : true , OAuthAudience : "mcp-server" }, OidcProvider : oidcProvider }, func (ctx * httpContext ) {
525
+ testCaseWithContext (t , & httpContext {StaticConfig : & config.StaticConfig {RequireOAuth : true , OAuthAudience : "mcp-server" , ValidateToken : true }, OidcProvider : oidcProvider }, func (ctx * httpContext ) {
526
526
req , err := http .NewRequest ("GET" , fmt .Sprintf ("http://%s/mcp" , ctx .HttpAddress ), nil )
527
527
if err != nil {
528
528
t .Fatalf ("Failed to create request: %v" , err )
@@ -559,7 +559,7 @@ func TestAuthorizationUnauthorized(t *testing.T) {
559
559
"aud": "mcp-server"
560
560
}`
561
561
validOidcToken := oidctest .SignIDToken (key , "test-oidc-key-id" , oidc .RS256 , rawClaims )
562
- testCaseWithContext (t , & httpContext {StaticConfig : & config.StaticConfig {RequireOAuth : true , OAuthAudience : "mcp-server" }, OidcProvider : oidcProvider }, func (ctx * httpContext ) {
562
+ testCaseWithContext (t , & httpContext {StaticConfig : & config.StaticConfig {RequireOAuth : true , OAuthAudience : "mcp-server" , ValidateToken : true }, OidcProvider : oidcProvider }, func (ctx * httpContext ) {
563
563
req , err := http .NewRequest ("GET" , fmt .Sprintf ("http://%s/mcp" , ctx .HttpAddress ), nil )
564
564
if err != nil {
565
565
t .Fatalf ("Failed to create request: %v" , err )
@@ -583,7 +583,8 @@ func TestAuthorizationUnauthorized(t *testing.T) {
583
583
}
584
584
})
585
585
t .Run ("Protected resource with INVALID KUBERNETES Authorization header logs error" , func (t * testing.T ) {
586
- if ! strings .Contains (ctx .LogBuffer .String (), "Authentication failed - API Server token validation error" ) {
586
+ if ! strings .Contains (ctx .LogBuffer .String (), "Authentication failed - JWT validation error" ) ||
587
+ ! strings .Contains (ctx .LogBuffer .String (), "kubernetes API token validation error: failed to create token review" ) {
587
588
t .Errorf ("Expected log entry for Kubernetes TokenReview error, got: %s" , ctx .LogBuffer .String ())
588
589
}
589
590
})
@@ -607,12 +608,17 @@ func TestAuthorizationRequireOAuthFalse(t *testing.T) {
607
608
}
608
609
609
610
func TestAuthorizationRawToken (t * testing.T ) {
610
- cases := []string {
611
- "" ,
612
- "mcp-server" ,
611
+ cases := []struct {
612
+ audience string
613
+ validateToken bool
614
+ }{
615
+ {"" , false }, // No audience, no validation
616
+ {"" , true }, // No audience, validation enabled
617
+ {"mcp-server" , false }, // Audience set, no validation
618
+ {"mcp-server" , true }, // Audience set, validation enabled
613
619
}
614
- for _ , audience := range cases {
615
- testCaseWithContext (t , & httpContext {StaticConfig : & config.StaticConfig {RequireOAuth : true , OAuthAudience : audience }}, func (ctx * httpContext ) {
620
+ for _ , c := range cases {
621
+ testCaseWithContext (t , & httpContext {StaticConfig : & config.StaticConfig {RequireOAuth : true , OAuthAudience : c . audience , ValidateToken : c . validateToken }}, func (ctx * httpContext ) {
616
622
ctx .mockServer .Handle (http .HandlerFunc (func (w http.ResponseWriter , req * http.Request ) {
617
623
if req .URL .EscapedPath () == "/apis/authentication.k8s.io/v1/tokenreviews" {
618
624
w .Header ().Set ("Content-Type" , "application/json" )
@@ -630,7 +636,7 @@ func TestAuthorizationRawToken(t *testing.T) {
630
636
t .Fatalf ("Failed to get protected endpoint: %v" , err )
631
637
}
632
638
t .Cleanup (func () { _ = resp .Body .Close () })
633
- t .Run ("Protected resource with audience = '" + audience + "' with VALID Authorization header returns 200 - OK" , func (t * testing.T ) {
639
+ t .Run (fmt . Sprintf ( "Protected resource with audience = '%s' and validate-token = '%t', with VALID Authorization header returns 200 - OK" , c . audience , c . validateToken ) , func (t * testing.T ) {
634
640
if resp .StatusCode != http .StatusOK {
635
641
t .Errorf ("Expected HTTP 200 OK, got %d" , resp .StatusCode )
636
642
}
@@ -649,28 +655,32 @@ func TestAuthorizationOidcToken(t *testing.T) {
649
655
"aud": "mcp-server"
650
656
}`
651
657
validOidcToken := oidctest .SignIDToken (key , "test-oidc-key-id" , oidc .RS256 , rawClaims )
652
- testCaseWithContext (t , & httpContext {StaticConfig : & config.StaticConfig {RequireOAuth : true , OAuthAudience : "mcp-server" }, OidcProvider : oidcProvider }, func (ctx * httpContext ) {
653
- ctx .mockServer .Handle (http .HandlerFunc (func (w http.ResponseWriter , req * http.Request ) {
654
- if req .URL .EscapedPath () == "/apis/authentication.k8s.io/v1/tokenreviews" {
655
- w .Header ().Set ("Content-Type" , "application/json" )
656
- _ , _ = w .Write ([]byte (tokenReviewSuccessful ))
657
- return
658
- }
659
- }))
660
- req , err := http .NewRequest ("GET" , fmt .Sprintf ("http://%s/mcp" , ctx .HttpAddress ), nil )
661
- if err != nil {
662
- t .Fatalf ("Failed to create request: %v" , err )
663
- }
664
- req .Header .Set ("Authorization" , "Bearer " + validOidcToken )
665
- resp , err := http .DefaultClient .Do (req )
666
- if err != nil {
667
- t .Fatalf ("Failed to get protected endpoint: %v" , err )
668
- }
669
- t .Cleanup (func () { _ = resp .Body .Close () })
670
- t .Run ("Protected resource with VALID OIDC Authorization header returns 200 - OK" , func (t * testing.T ) {
671
- if resp .StatusCode != http .StatusOK {
672
- t .Errorf ("Expected HTTP 200 OK, got %d" , resp .StatusCode )
658
+ cases := []bool {false , true }
659
+ for _ , validateToken := range cases {
660
+ testCaseWithContext (t , & httpContext {StaticConfig : & config.StaticConfig {RequireOAuth : true , OAuthAudience : "mcp-server" , ValidateToken : validateToken }, OidcProvider : oidcProvider }, func (ctx * httpContext ) {
661
+ ctx .mockServer .Handle (http .HandlerFunc (func (w http.ResponseWriter , req * http.Request ) {
662
+ if req .URL .EscapedPath () == "/apis/authentication.k8s.io/v1/tokenreviews" {
663
+ w .Header ().Set ("Content-Type" , "application/json" )
664
+ _ , _ = w .Write ([]byte (tokenReviewSuccessful ))
665
+ return
666
+ }
667
+ }))
668
+ req , err := http .NewRequest ("GET" , fmt .Sprintf ("http://%s/mcp" , ctx .HttpAddress ), nil )
669
+ if err != nil {
670
+ t .Fatalf ("Failed to create request: %v" , err )
671
+ }
672
+ req .Header .Set ("Authorization" , "Bearer " + validOidcToken )
673
+ resp , err := http .DefaultClient .Do (req )
674
+ if err != nil {
675
+ t .Fatalf ("Failed to get protected endpoint: %v" , err )
673
676
}
677
+ t .Cleanup (func () { _ = resp .Body .Close () })
678
+ t .Run (fmt .Sprintf ("Protected resource with validate-token='%t' with VALID OIDC Authorization header returns 200 - OK" , validateToken ), func (t * testing.T ) {
679
+ if resp .StatusCode != http .StatusOK {
680
+ t .Errorf ("Expected HTTP 200 OK, got %d" , resp .StatusCode )
681
+ }
682
+ })
674
683
})
675
- })
684
+
685
+ }
676
686
}
0 commit comments