...
1 package keyfunc_test
2
3 import (
4 "net/http"
5 "net/http/httptest"
6 "testing"
7
8 "github.com/golang-jwt/jwt/v5"
9
10 "github.com/MicahParks/keyfunc/v2"
11 )
12
13 const (
14 jwks1 = `{"keys":[{"alg":"EdDSA","crv":"Ed25519","kid":"uniqueKID","kty":"OKP","x":"1IlXuWBIkjYbAXm5Hk5mvsbPq0skO3-G_hX1Cw7CY-8"},{"alg":"EdDSA","crv":"Ed25519","kid":"collisionKID","kty":"OKP","x":"IbQyt_GPqUJImuAgStdixWdadZGvzTPS_mKlOjmuOYU"}]}`
15 jwks2 = `{"keys":[{"alg":"EdDSA","crv":"Ed25519","kid":"collisionKID","kty":"OKP","x":"IbQyt_GPqUJImuAgStdixWdadZGvzTPS_mKlOjmuOYU"}]}`
16 )
17
18 func TestMultipleJWKS(t *testing.T) {
19 server1 := createTestServer([]byte(jwks1))
20 defer server1.Close()
21
22 server2 := createTestServer([]byte(jwks2))
23 defer server2.Close()
24
25 const (
26 collisionJWT = "eyJhbGciOiJFZERTQSIsImtpZCI6ImNvbGxpc2lvbktJRCIsInR5cCI6IkpXVCJ9.e30.WXKmhyHjHQFXZ8dXfj07RvwKAgHB3EdGU1jeKUEY-wajgsRsHuhnotX1WqDSlngwGerEitnIcdMGViW_HNUCAA"
27 uniqueJWT = "eyJhbGciOiJFZERTQSIsImtpZCI6InVuaXF1ZUtJRCIsInR5cCI6IkpXVCJ9.e30.egdT5_vXYKIM7UfsyewYaR63tS9T9JvKwUJs7Srj6wG9JHXMvN9Ftq0rJGem07ESVtN5OtlcJOaMgSbtxnc6Bg"
28 )
29
30 m := map[string]keyfunc.Options{
31 server1.URL: {},
32 server2.URL: {},
33 }
34
35 multiJWKS, err := keyfunc.GetMultiple(m, keyfunc.MultipleOptions{})
36 if err != nil {
37 t.Fatalf("failed to get multiple JWKS: %v", err)
38 }
39
40 token, err := jwt.Parse(collisionJWT, multiJWKS.Keyfunc)
41 if err != nil {
42 t.Fatalf("failed to parse collision JWT: %v", err)
43 }
44 if !token.Valid {
45 t.Fatalf("collision JWT is invalid")
46 }
47
48 token, err = jwt.Parse(uniqueJWT, multiJWKS.Keyfunc)
49 if err != nil {
50 t.Fatalf("failed to parse unique JWT: %v", err)
51 }
52 if !token.Valid {
53 t.Fatalf("unique JWT is invalid")
54 }
55
56 sets := multiJWKS.JWKSets()
57 if len(sets) != 2 {
58 t.Fatalf("expected 2 JWKS, got %d", len(sets))
59 }
60 }
61
62 func TestMultipleJWKSSingle(t *testing.T) {
63 server1 := createTestServer([]byte(jwks1))
64 defer server1.Close()
65
66 const (
67 collisionJWT = "eyJhbGciOiJFZERTQSIsImtpZCI6ImNvbGxpc2lvbktJRCIsInR5cCI6IkpXVCJ9.e30.WXKmhyHjHQFXZ8dXfj07RvwKAgHB3EdGU1jeKUEY-wajgsRsHuhnotX1WqDSlngwGerEitnIcdMGViW_HNUCAA"
68 uniqueJWT = "eyJhbGciOiJFZERTQSIsImtpZCI6InVuaXF1ZUtJRCIsInR5cCI6IkpXVCJ9.e30.egdT5_vXYKIM7UfsyewYaR63tS9T9JvKwUJs7Srj6wG9JHXMvN9Ftq0rJGem07ESVtN5OtlcJOaMgSbtxnc6Bg"
69 )
70
71 m := map[string]keyfunc.Options{
72 server1.URL: {},
73 }
74
75 multiJWKS, err := keyfunc.GetMultiple(m, keyfunc.MultipleOptions{})
76 if err != nil {
77 t.Fatalf("failed to get multiple JWKS: %v", err)
78 }
79
80 token, err := jwt.Parse(collisionJWT, multiJWKS.Keyfunc)
81 if err != nil {
82 t.Fatalf("failed to parse collision JWT: %v", err)
83 }
84 if !token.Valid {
85 t.Fatalf("collision JWT is invalid")
86 }
87
88 token, err = jwt.Parse(uniqueJWT, multiJWKS.Keyfunc)
89 if err != nil {
90 t.Fatalf("failed to parse unique JWT: %v", err)
91 }
92 if !token.Valid {
93 t.Fatalf("unique JWT is invalid")
94 }
95
96 sets := multiJWKS.JWKSets()
97 if len(sets) != 1 {
98 t.Fatalf("expected 2 JWKS, got %d", len(sets))
99 }
100 }
101
102 func createTestServer(body []byte) *httptest.Server {
103 return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
104 w.Header().Set("Content-Type", "application/json")
105 _, _ = w.Write(body)
106 }))
107 }
108
View as plain text