github.com/fedir/buffalo@v0.11.1/middleware/tokenauth/tokenauth_test.go (about) 1 package tokenauth_test 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "log" 7 "net/http" 8 "testing" 9 "time" 10 11 "github.com/dgrijalva/jwt-go" 12 "github.com/gobuffalo/envy" 13 "github.com/pkg/errors" 14 15 "github.com/gobuffalo/buffalo" 16 "github.com/gobuffalo/buffalo/middleware/tokenauth" 17 "github.com/markbates/willie" 18 "github.com/stretchr/testify/require" 19 ) 20 21 func appHMAC() *buffalo.App { 22 h := func(c buffalo.Context) error { 23 return c.Render(200, nil) 24 } 25 envy.Set("JWT_SECRET", "secret") 26 a := buffalo.New(buffalo.Options{}) 27 // if method not specified it will use HMAC 28 a.Use(tokenauth.New(tokenauth.Options{ 29 GetKey: tokenauth.GetHMACKey, 30 })) 31 a.GET("/", h) 32 return a 33 } 34 func appRSA() *buffalo.App { 35 h := func(c buffalo.Context) error { 36 return c.Render(200, nil) 37 } 38 envy.Set("JWT_PUBLIC_KEY", "test_certs/sample_key.pub") 39 a := buffalo.New(buffalo.Options{}) 40 a.Use(tokenauth.New(tokenauth.Options{ 41 SignMethod: jwt.SigningMethodRS256, 42 })) 43 a.GET("/", h) 44 return a 45 } 46 47 func appRSAPSS() *buffalo.App { 48 h := func(c buffalo.Context) error { 49 return c.Render(200, nil) 50 } 51 envy.Set("JWT_PUBLIC_KEY", "test_certs/sample_key.pub") 52 a := buffalo.New(buffalo.Options{}) 53 a.Use(tokenauth.New(tokenauth.Options{ 54 SignMethod: jwt.SigningMethodPS256, 55 GetKey: tokenauth.GetKeyRSAPSS, 56 })) 57 a.GET("/", h) 58 return a 59 } 60 61 func appECDSA() *buffalo.App { 62 h := func(c buffalo.Context) error { 63 return c.Render(200, nil) 64 } 65 envy.Set("JWT_PUBLIC_KEY", "test_certs/ec256-public.pem") 66 67 a := buffalo.New(buffalo.Options{}) 68 a.Use(tokenauth.New(tokenauth.Options{ 69 SignMethod: jwt.SigningMethodES256, 70 })) 71 a.GET("/", h) 72 return a 73 } 74 75 // Test HMAC 76 func TestTokenHMAC(t *testing.T) { 77 r := require.New(t) 78 w := willie.New(appHMAC()) 79 80 // Missing Authorization 81 res := w.Request("/").Get() 82 r.Equal(http.StatusUnauthorized, res.Code) 83 84 // invalid token 85 req := w.Request("/") 86 req.Headers["Authorization"] = "badcreds" 87 res = req.Get() 88 r.Equal(http.StatusUnauthorized, res.Code) 89 r.Contains(res.Body.String(), "token invalid") 90 91 // expired token 92 secretKey := envy.Get("JWT_SECRET", "secret") 93 claims := jwt.MapClaims{} 94 claims["sub"] = "1234567890" 95 claims["exp"] = time.Now().Add(-time.Minute * 5).Unix() 96 97 token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) 98 tokenString, _ := token.SignedString([]byte(secretKey)) 99 req.Headers["Authorization"] = fmt.Sprintf("Bearer %s", tokenString) 100 res = req.Get() 101 //fmt.Println(res.Body.String()) 102 r.Equal(http.StatusUnauthorized, res.Code) 103 r.Contains(res.Body.String(), "Token is expired") 104 105 // valid token 106 claims["exp"] = time.Now().Add(time.Minute * 5).Unix() 107 token = jwt.NewWithClaims(jwt.SigningMethodHS256, claims) 108 tokenString, _ = token.SignedString([]byte(secretKey)) 109 req.Headers["Authorization"] = fmt.Sprintf("Bearer %s", tokenString) 110 res = req.Get() 111 r.Equal(http.StatusOK, res.Code) 112 } 113 114 // Test RSA 115 func TestTokenRSA(t *testing.T) { 116 r := require.New(t) 117 w := willie.New(appRSA()) 118 119 // Missing Authorization 120 res := w.Request("/").Get() 121 r.Equal(http.StatusUnauthorized, res.Code) 122 123 // invalid token 124 req := w.Request("/") 125 req.Headers["Authorization"] = "badcreds" 126 res = req.Get() 127 r.Equal(http.StatusUnauthorized, res.Code) 128 r.Contains(res.Body.String(), "token invalid") 129 130 // expired token 131 privateKeyFile := envy.Get("JWT_PRIVATE_KEY", "test_certs/sample_key") 132 key, err := ioutil.ReadFile(privateKeyFile) 133 if err != nil { 134 log.Fatal(err) 135 } 136 parsedKey, err := jwt.ParseRSAPrivateKeyFromPEM(key) 137 if err != nil { 138 log.Fatal(errors.Wrap(err, "error parsing key")) 139 } 140 claims := jwt.MapClaims{} 141 claims["sub"] = "1234567890" 142 claims["exp"] = time.Now().Add(-time.Minute * 5).Unix() 143 144 token := jwt.NewWithClaims(jwt.SigningMethodRS256, claims) 145 tokenString, err := token.SignedString(parsedKey) 146 if err != nil { 147 log.Fatal(errors.Wrap(err, "error signing token")) 148 } 149 req.Headers["Authorization"] = fmt.Sprintf("Bearer %s", tokenString) 150 res = req.Get() 151 r.Equal(http.StatusUnauthorized, res.Code) 152 r.Contains(res.Body.String(), "Token is expired") 153 154 // valid token 155 claims["exp"] = time.Now().Add(time.Minute * 5).Unix() 156 token = jwt.NewWithClaims(jwt.SigningMethodRS256, claims) 157 tokenString, _ = token.SignedString(parsedKey) 158 req.Headers["Authorization"] = fmt.Sprintf("Bearer %s", tokenString) 159 res = req.Get() 160 r.Equal(http.StatusOK, res.Code) 161 } 162 163 // Test ECDSA 164 func TestTokenECDSA(t *testing.T) { 165 r := require.New(t) 166 w := willie.New(appECDSA()) 167 168 // Missing Authorization 169 res := w.Request("/").Get() 170 r.Equal(http.StatusUnauthorized, res.Code) 171 172 // invalid token 173 req := w.Request("/") 174 req.Headers["Authorization"] = "badcreds" 175 res = req.Get() 176 r.Equal(http.StatusUnauthorized, res.Code) 177 r.Contains(res.Body.String(), "token invalid") 178 179 // expired token 180 privateKeyFile := envy.Get("JWT_PRIVATE_KEY", "test_certs/ec256-private.pem") 181 key, err := ioutil.ReadFile(privateKeyFile) 182 if err != nil { 183 log.Fatal(errors.Wrap(err, "error reading keyfile")) 184 } 185 parsedKey, err := jwt.ParseECPrivateKeyFromPEM(key) 186 if err != nil { 187 log.Fatal(errors.Wrap(err, "error parsing key")) 188 } 189 claims := jwt.MapClaims{} 190 claims["sub"] = "1234567890" 191 claims["exp"] = time.Now().Add(-time.Minute * 5).Unix() 192 token := jwt.NewWithClaims(jwt.SigningMethodES256, claims) 193 tokenString, err := token.SignedString(parsedKey) 194 if err != nil { 195 log.Fatal(errors.Wrap(err, "error signing token")) 196 } 197 req.Headers["Authorization"] = fmt.Sprintf("Bearer %s", tokenString) 198 res = req.Get() 199 r.Equal(http.StatusUnauthorized, res.Code) 200 r.Contains(res.Body.String(), "Token is expired") 201 202 // valid token 203 claims["exp"] = time.Now().Add(time.Minute * 5).Unix() 204 token = jwt.NewWithClaims(jwt.SigningMethodES256, claims) 205 tokenString, _ = token.SignedString(parsedKey) 206 req.Headers["Authorization"] = fmt.Sprintf("Bearer %s", tokenString) 207 res = req.Get() 208 r.Equal(http.StatusOK, res.Code) 209 } 210 211 // Test RSAPSS 212 func TestTokenRSAPSS(t *testing.T) { 213 r := require.New(t) 214 w := willie.New(appRSAPSS()) 215 216 // Missing Authorization 217 res := w.Request("/").Get() 218 r.Equal(http.StatusUnauthorized, res.Code) 219 220 // invalid token 221 req := w.Request("/") 222 req.Headers["Authorization"] = "badcreds" 223 res = req.Get() 224 r.Equal(http.StatusUnauthorized, res.Code) 225 r.Contains(res.Body.String(), "token invalid") 226 227 // expired token 228 privateKeyFile := envy.Get("JWT_PRIVATE_KEY", "test_certs/sample_key") 229 key, err := ioutil.ReadFile(privateKeyFile) 230 if err != nil { 231 log.Fatal(err) 232 } 233 parsedKey, err := jwt.ParseRSAPrivateKeyFromPEM(key) 234 if err != nil { 235 log.Fatal(errors.Wrap(err, "error parsing key")) 236 } 237 claims := jwt.MapClaims{} 238 claims["sub"] = "1234567890" 239 claims["exp"] = time.Now().Add(-time.Minute * 5).Unix() 240 241 token := jwt.NewWithClaims(jwt.SigningMethodPS256, claims) 242 tokenString, err := token.SignedString(parsedKey) 243 if err != nil { 244 log.Fatal(errors.Wrap(err, "error signing token")) 245 } 246 req.Headers["Authorization"] = fmt.Sprintf("Bearer %s", tokenString) 247 res = req.Get() 248 r.Equal(http.StatusUnauthorized, res.Code) 249 r.Contains(res.Body.String(), "Token is expired") 250 251 // valid token 252 claims["exp"] = time.Now().Add(time.Minute * 5).Unix() 253 token = jwt.NewWithClaims(jwt.SigningMethodPS256, claims) 254 tokenString, _ = token.SignedString(parsedKey) 255 req.Headers["Authorization"] = fmt.Sprintf("Bearer %s", tokenString) 256 res = req.Get() 257 r.Equal(http.StatusOK, res.Code) 258 }