@@ -284,7 +284,7 @@ func TestHealthCheck(t *testing.T) {
284284 })
285285 })
286286 // 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 ) {
288288 resp , err := http .Get (fmt .Sprintf ("http://%s/healthz" , ctx .HttpAddress ))
289289 if err != nil {
290290 t .Fatalf ("Failed to get health check endpoint with OAuth: %v" , err )
@@ -305,7 +305,7 @@ func TestWellKnownReverseProxy(t *testing.T) {
305305 ".well-known/openid-configuration" ,
306306 }
307307 // 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 ) {
309309 for _ , path := range cases {
310310 resp , err := http .Get (fmt .Sprintf ("http://%s/%s" , ctx .HttpAddress , path ))
311311 t .Cleanup (func () { _ = resp .Body .Close () })
@@ -329,7 +329,7 @@ func TestWellKnownReverseProxy(t *testing.T) {
329329 _ , _ = w .Write ([]byte (`{"issuer": "https://example.com","scopes_supported":["mcp-server"]}` ))
330330 }))
331331 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 ) {
333333 for _ , path := range cases {
334334 resp , err := http .Get (fmt .Sprintf ("http://%s/%s" , ctx .HttpAddress , path ))
335335 t .Cleanup (func () { _ = resp .Body .Close () })
@@ -377,7 +377,7 @@ func TestMiddlewareLogging(t *testing.T) {
377377
378378func TestAuthorizationUnauthorized (t * testing.T ) {
379379 // 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 ) {
381381 resp , err := http .Get (fmt .Sprintf ("http://%s/mcp" , ctx .HttpAddress ))
382382 if err != nil {
383383 t .Fatalf ("Failed to get protected endpoint: %v" , err )
@@ -402,7 +402,7 @@ func TestAuthorizationUnauthorized(t *testing.T) {
402402 })
403403 })
404404 // 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 ) {
406406 req , err := http .NewRequest ("GET" , fmt .Sprintf ("http://%s/mcp" , ctx .HttpAddress ), nil )
407407 if err != nil {
408408 t .Fatalf ("Failed to create request: %v" , err )
@@ -427,7 +427,7 @@ func TestAuthorizationUnauthorized(t *testing.T) {
427427 })
428428 })
429429 // 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 ) {
431431 req , err := http .NewRequest ("GET" , fmt .Sprintf ("http://%s/mcp" , ctx .HttpAddress ), nil )
432432 if err != nil {
433433 t .Fatalf ("Failed to create request: %v" , err )
@@ -458,7 +458,7 @@ func TestAuthorizationUnauthorized(t *testing.T) {
458458 })
459459 })
460460 // 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 ) {
462462 req , err := http .NewRequest ("GET" , fmt .Sprintf ("http://%s/mcp" , ctx .HttpAddress ), nil )
463463 if err != nil {
464464 t .Fatalf ("Failed to create request: %v" , err )
@@ -489,7 +489,7 @@ func TestAuthorizationUnauthorized(t *testing.T) {
489489 })
490490 })
491491 // 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 ) {
493493 req , err := http .NewRequest ("GET" , fmt .Sprintf ("http://%s/mcp" , ctx .HttpAddress ), nil )
494494 if err != nil {
495495 t .Fatalf ("Failed to create request: %v" , err )
@@ -522,7 +522,7 @@ func TestAuthorizationUnauthorized(t *testing.T) {
522522 // Failed OIDC validation
523523 key , oidcProvider , httpServer := NewOidcTestServer (t )
524524 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 ) {
526526 req , err := http .NewRequest ("GET" , fmt .Sprintf ("http://%s/mcp" , ctx .HttpAddress ), nil )
527527 if err != nil {
528528 t .Fatalf ("Failed to create request: %v" , err )
@@ -559,7 +559,7 @@ func TestAuthorizationUnauthorized(t *testing.T) {
559559 "aud": "mcp-server"
560560 }`
561561 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 ) {
563563 req , err := http .NewRequest ("GET" , fmt .Sprintf ("http://%s/mcp" , ctx .HttpAddress ), nil )
564564 if err != nil {
565565 t .Fatalf ("Failed to create request: %v" , err )
@@ -583,7 +583,8 @@ func TestAuthorizationUnauthorized(t *testing.T) {
583583 }
584584 })
585585 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" ) {
587588 t .Errorf ("Expected log entry for Kubernetes TokenReview error, got: %s" , ctx .LogBuffer .String ())
588589 }
589590 })
@@ -607,12 +608,17 @@ func TestAuthorizationRequireOAuthFalse(t *testing.T) {
607608}
608609
609610func 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
613619 }
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 ) {
616622 ctx .mockServer .Handle (http .HandlerFunc (func (w http.ResponseWriter , req * http.Request ) {
617623 if req .URL .EscapedPath () == "/apis/authentication.k8s.io/v1/tokenreviews" {
618624 w .Header ().Set ("Content-Type" , "application/json" )
@@ -630,7 +636,7 @@ func TestAuthorizationRawToken(t *testing.T) {
630636 t .Fatalf ("Failed to get protected endpoint: %v" , err )
631637 }
632638 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 ) {
634640 if resp .StatusCode != http .StatusOK {
635641 t .Errorf ("Expected HTTP 200 OK, got %d" , resp .StatusCode )
636642 }
@@ -649,28 +655,32 @@ func TestAuthorizationOidcToken(t *testing.T) {
649655 "aud": "mcp-server"
650656 }`
651657 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 )
673676 }
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+ })
674683 })
675- })
684+
685+ }
676686}
0 commit comments