forked from TykTechnologies/tyk
-
Notifications
You must be signed in to change notification settings - Fork 0
/
middleware_jwt_test.go
242 lines (216 loc) · 7.82 KB
/
middleware_jwt_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
package main
import (
//"encoding/base64"
//"fmt"
"github.com/dgrijalva/jwt-go"
"net/http"
"net/http/httptest"
"net/url"
//"strings"
"testing"
"time"
"github.com/justinas/alice"
)
var jwtDef string = `
{
"name": "Tyk JWT API",
"api_id": "76",
"org_id": "default",
"definition": {
"location": "header",
"key": "version"
},
"enable_jwt": true,
"auth": {
"auth_header_name": "authorization"
},
"version_data": {
"not_versioned": true,
"versions": {
"Default": {
"name": "Default",
"use_extended_paths": true,
"expires": "3000-01-02 15:04",
"paths": {
"ignored": [],
"white_list": [],
"black_list": []
}
}
}
},
"proxy": {
"listen_path": "/jwt_test",
"target_url": "http://example.com/",
"strip_listen_path": true
}
}
`
const JWTSECRET string = "9879879878787878"
// openssl genrsa -out app.rsa
const JWTRSA_PRIVKEY string = `
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEAyqZ4rwKF8qCExS7kpY4cnJa/37FMkJNkalZ3OuslLB0oRL8T
4c94kdF4aeNzSFkSe2n99IBI6Ssl79vbfMZb+t06L0Q94k+/P37x7+/RJZiff4y1
VGjrnrnMI2iu9l4iBBRYzNmG6eblroEMMWlgk5tysHgxB59CSNIcD9gqk1hx4n/F
gOmvKsfQgWHNlPSDTRcWGWGhB2/XgNVYG2pOlQxAPqLhBHeqGTXBbPfGF9cHzixp
sPr6GtbzPwhsQ/8bPxoJ7hdfn+rzztks3d6+HWURcyNTLRe0mjXjjee9Z6+gZ+H+
fS4pnP9tqT7IgU6ePUWTpjoiPtLexgsAa/ctjQIDAQABAoIBAECWvnBJRZgHQUn3
oDiECup9wbnyMI0D7UVXObk1qSteP69pl1SpY6xWLyLQs7WjbhiXt7FuEc7/SaAh
Wttx/W7/g8P85Bx1fmcmdsYakXaCJpPorQKyTibQ4ReIDfvIFN9n/MWNr0ptpVbx
GonFJFrneK52IGplgCLllLwYEbnULYcJc6E25Ro8U2gQjF2r43PDa07YiDrmB/GV
QQW4HTo+CA9rdK0bP8GpXgc0wpmBhx/t/YdnDg6qhzyUMk9As7JrAzYPjHO0cRun
vhA/aG/mdMmRumY75nj7wB5U5DgstsN2ER75Pjr1xe1knftIyNm15AShCPfLaLGo
dA2IpwECgYEA5E8h6ssa7QroCGwp/N0wSJW41hFYGygbOEg6yPWTJkqmMZVduD8X
/KFqJK4LcIbFQuR28+hWJpHm/RF1AMRhbbWkAj6h02gv5izFwDiFKev5paky4Evg
G8WfUOmSZ1D+fVxwaoG0OaRZpCovUTxYig3xrI659DMeKqpQ7e8l9ekCgYEA4zql
l4P4Dn0ydr+TI/s4NHIQHkaLQAVk3OWwyKowijXd8LCtuZRA1NKSpqQ4ZXi0B17o
9zzF5jEUjws3qWv4PKWdxJu3y+h/etsg7wxUeNizbY2ooUGeMbk0tWxJihbgaI7E
XxLIT50F3Ky4EJ2cUL9GmJ+gLCw0KIaVbkiyYAUCgYEA0WyVHB76r/2VIkS1rzHm
HG7ageKfAyoi7dmzsqsxM6q+EDWHJn8Zra8TAlp0O+AkClwvkUTJ4c9sJy9gODfr
dwtrSnPRVW74oRbovo4Z+H5xHbi65mwzQsZggYP/u63cA3pL1Cbt/wH3CFN52/aS
8PAhg7vYb1yEi3Z3jgoUtCECgYEAhSPX4u9waQzyhKG7lVmdlR1AVH0BGoIOl1/+
NZWC23i0klLzd8lmM00uoHWYldwjoC38UuFJE5eudCIeeybITMC9sHWNO+z+xP2g
TnDrDePrPkXCiLnp9ziNqb/JVyAQXTNJ3Gsk84EN7j9Fmna/IJDyzHq7XyaHaTdy
VyxBWAECgYEA4jYS07bPx5UMhKiMJDqUmDfLNFD97XwPoJIkOdn6ezqeOSmlmo7t
jxHLbCmsDOAsCU/0BlLXg9wMU7n5QKSlfTVGok/PU0rq2FUXQwyKGnellrqODwFQ
YGivtXBGXk1hlVYlje1RB+W6RQuDAegI5h8vl8pYJS9JQH0wjatsDaE=
-----END RSA PRIVATE KEY-----
`
// openssl rsa -in app.rsa -pubout > app.rsa.pub
const JWTRSA_PUBKEY string = `
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyqZ4rwKF8qCExS7kpY4c
nJa/37FMkJNkalZ3OuslLB0oRL8T4c94kdF4aeNzSFkSe2n99IBI6Ssl79vbfMZb
+t06L0Q94k+/P37x7+/RJZiff4y1VGjrnrnMI2iu9l4iBBRYzNmG6eblroEMMWlg
k5tysHgxB59CSNIcD9gqk1hx4n/FgOmvKsfQgWHNlPSDTRcWGWGhB2/XgNVYG2pO
lQxAPqLhBHeqGTXBbPfGF9cHzixpsPr6GtbzPwhsQ/8bPxoJ7hdfn+rzztks3d6+
HWURcyNTLRe0mjXjjee9Z6+gZ+H+fS4pnP9tqT7IgU6ePUWTpjoiPtLexgsAa/ct
jQIDAQAB
-----END PUBLIC KEY-----
`
func createJWTSession() SessionState {
var thisSession SessionState
thisSession.Rate = 8.0
thisSession.Allowance = thisSession.Rate
thisSession.LastCheck = time.Now().Unix()
thisSession.Per = 1.0
thisSession.Expires = 0
thisSession.QuotaRenewalRate = 300 // 5 minutes
thisSession.QuotaRenews = time.Now().Unix() + 20
thisSession.QuotaRemaining = 1
thisSession.QuotaMax = -1
thisSession.JWTData.Secret = JWTSECRET
return thisSession
}
func createJWTSessionWithRSA() SessionState {
var thisSession SessionState
thisSession.Rate = 8.0
thisSession.Allowance = thisSession.Rate
thisSession.LastCheck = time.Now().Unix()
thisSession.Per = 1.0
thisSession.Expires = 0
thisSession.QuotaRenewalRate = 300 // 5 minutes
thisSession.QuotaRenews = time.Now().Unix() + 20
thisSession.QuotaRemaining = 1
thisSession.QuotaMax = -1
thisSession.JWTData.Secret = JWTRSA_PUBKEY
return thisSession
}
func getJWTChain(spec APISpec) http.Handler {
redisStore := RedisStorageManager{KeyPrefix: "apikey-"}
healthStore := &RedisStorageManager{KeyPrefix: "apihealth."}
orgStore := &RedisStorageManager{KeyPrefix: "orgKey."}
spec.Init(&redisStore, &redisStore, healthStore, orgStore)
remote, _ := url.Parse("http://lonelycode.com/")
proxy := TykNewSingleHostReverseProxy(remote, &spec)
proxyHandler := http.HandlerFunc(ProxyHandler(proxy, &spec))
tykMiddleware := &TykMiddleware{&spec, proxy}
chain := alice.New(
CreateMiddleware(&IPWhiteListMiddleware{tykMiddleware}, tykMiddleware),
CreateMiddleware(&JWTMiddleware{tykMiddleware}, tykMiddleware),
CreateMiddleware(&VersionCheck{TykMiddleware: tykMiddleware}, tykMiddleware),
CreateMiddleware(&KeyExpired{tykMiddleware}, tykMiddleware),
CreateMiddleware(&AccessRightsCheck{tykMiddleware}, tykMiddleware),
CreateMiddleware(&RateLimitAndQuotaCheck{tykMiddleware}, tykMiddleware)).Then(proxyHandler)
return chain
}
func TestJWTSessionHMAC(t *testing.T) {
var thisTokenKID string = "78787885454"
spec := createDefinitionFromString(jwtDef)
spec.JWTSigningMethod = "hmac"
redisStore := RedisStorageManager{KeyPrefix: "apikey-"}
healthStore := &RedisStorageManager{KeyPrefix: "apihealth."}
orgStore := &RedisStorageManager{KeyPrefix: "orgKey."}
spec.Init(&redisStore, &redisStore, healthStore, orgStore)
thisSession := createJWTSession()
spec.SessionManager.UpdateSession(thisTokenKID, thisSession, 60)
// Create the token
token := jwt.New(jwt.SigningMethodHS256)
// Set the token ID
token.Header["kid"] = thisTokenKID
// Set some claims
token.Claims["foo"] = "bar"
token.Claims["exp"] = time.Now().Add(time.Hour * 72).Unix()
// Sign and get the complete encoded token as a string
tokenString, err := token.SignedString([]byte(JWTSECRET))
if err != nil {
log.Error("Couldn't create JWT token: ")
t.Fatal(err)
}
log.Info(tokenString)
recorder := httptest.NewRecorder()
param := make(url.Values)
req, err := http.NewRequest("GET", "/jwt_test/?"+param.Encode(), nil)
req.Header.Add("authorization", tokenString)
if err != nil {
log.Error("Problem generating the test token: ", err)
}
chain := getJWTChain(spec)
chain.ServeHTTP(recorder, req)
if recorder.Code != 200 {
t.Error("Initial request failed with non-200 code, should have gone through!: \n", recorder.Code)
}
}
func TestJWTSessionRSA(t *testing.T) {
var thisTokenKID string = "2342342343434234"
spec := createDefinitionFromString(jwtDef)
spec.JWTSigningMethod = "rsa"
redisStore := RedisStorageManager{KeyPrefix: "apikey-"}
healthStore := &RedisStorageManager{KeyPrefix: "apihealth."}
orgStore := &RedisStorageManager{KeyPrefix: "orgKey."}
spec.Init(&redisStore, &redisStore, healthStore, orgStore)
thisSession := createJWTSessionWithRSA()
spec.SessionManager.UpdateSession(thisTokenKID, thisSession, 60)
// Create the token
token := jwt.New(jwt.GetSigningMethod("RS512"))
// Set the token ID
token.Header["kid"] = thisTokenKID
// Set some claims
token.Claims["foo"] = "bar"
token.Claims["exp"] = time.Now().Add(time.Hour * 72).Unix()
// Sign and get the complete encoded token as a string
signKey, getSignErr := jwt.ParseRSAPrivateKeyFromPEM([]byte(JWTRSA_PRIVKEY))
if getSignErr != nil {
log.Error("Couldn't extract private key: ")
t.Fatal(getSignErr)
}
tokenString, err := token.SignedString(signKey)
if err != nil {
log.Error("Couldn't create JWT token: ")
t.Fatal(err)
}
log.Info(tokenString)
recorder := httptest.NewRecorder()
param := make(url.Values)
req, err := http.NewRequest("GET", "/jwt_test/?"+param.Encode(), nil)
req.Header.Add("authorization", tokenString)
if err != nil {
log.Error("Problem generating the test token: ", err)
}
chain := getJWTChain(spec)
chain.ServeHTTP(recorder, req)
if recorder.Code != 200 {
t.Error("Initial request failed with non-200 code, should have gone through!: \n", recorder.Code)
}
}