package bouncer import ( "net/http" "net/http/httptest" "testing" "time" ) func TestAudienceCrossover(t *testing.T) { const secret = "same-secret-for-both-guards" users := memUsers{byID: map[uint]*Principal{1: {ID: 1}}} userTok, _, err := MintAudience(secret, "1", "https://app.test/login", time.Hour, AudienceUser) if err != nil { t.Fatal(err) } backendTok, _, err := MintAudience(secret, "1", "https://app.test/_admin/api/v1/auth/login", time.Hour, AudienceBackend) if err != nil { t.Fatal(err) } frontend := NewJWTGuard(secret, users, nil) backend := NewBackendJWTGuard(secret, users, nil, nil) if principal, err := backend.Authenticate(withBearer(backendTok)); err != nil || principal == nil || principal.ID != 1 { t.Fatalf("backend guard rejected its own audience: %v", err) } if principal, err := frontend.Authenticate(withBearer(userTok)); err != nil || principal == nil || principal.ID != 1 { t.Fatalf("frontend guard rejected its own audience: %v", err) } if principal, err := backend.Authenticate(withBearer(userTok)); err == nil || principal != nil { t.Fatal("backend guard accepted a frontend-audience token signed with the same secret") } if principal, err := frontend.Authenticate(withBearer(backendTok)); err == nil || principal != nil { t.Fatal("frontend guard accepted a backend-audience token signed with the same secret") } } func withBearer(token string) *http.Request { req := httptest.NewRequest(http.MethodGet, "/", nil) req.Header.Set("Authorization", "Bearer "+token) return req }