Skip to content

Commit

Permalink
replace server/path with service in token
Browse files Browse the repository at this point in the history
  • Loading branch information
je4 committed Nov 3, 2021
1 parent e6e85bc commit f55fb41
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 21 deletions.
12 changes: 8 additions & 4 deletions pkg/JWTInterceptor/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func checkToken(tokenStr string, jwtKey string, jwtAlg []string) (jwt.MapClaims,
return claims, nil
}

func JWTInterceptor(handler http.Handler, ignorePrefix string, jwtKey string, jwtAlg []string, h hash.Hash) http.Handler {
func JWTInterceptor(service string, handler http.Handler, jwtKey string, jwtAlg []string, h hash.Hash) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var err error

Expand Down Expand Up @@ -76,12 +76,12 @@ func JWTInterceptor(handler http.Handler, ignorePrefix string, jwtKey string, jw

// calculate checksum
h.Reset()
// checksum from method + path + url query params + body
if _, err := h.Write([]byte(strings.ToUpper(r.Method))); err != nil {
// checksum from service + method + url query params + body
if _, err := h.Write([]byte(service)); err != nil {
http.Error(w, fmt.Sprintf("JWTInterceptor: cannot write to checksum: %v", err), http.StatusInternalServerError)
return
}
if _, err := h.Write([]byte(strings.TrimPrefix(r.URL.Path, ignorePrefix))); err != nil {
if _, err := h.Write([]byte(strings.ToUpper(r.Method))); err != nil {
http.Error(w, fmt.Sprintf("JWTInterceptor: cannot write to checksum: %v", err), http.StatusInternalServerError)
return
}
Expand Down Expand Up @@ -111,6 +111,10 @@ func JWTInterceptor(handler http.Handler, ignorePrefix string, jwtKey string, jw
return
}

if service != claims["service"] {
http.Error(w, fmt.Sprintf("JWTInterceptor: invalid service: %s != %s", service, claims["service"]), http.StatusForbidden)
return
}
if checksum != claims["checksum"] {
http.Error(w, fmt.Sprintf("JWTInterceptor: invalid checksum: %s != %s", checksum, claims["checksum"]), http.StatusForbidden)
return
Expand Down
17 changes: 10 additions & 7 deletions pkg/JWTInterceptor/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func TestMain(m *testing.M) {
}

mux := http.NewServeMux()
mux.Handle("/test/sub", JWTInterceptor(hello(), "/test", "secret", []string{"HS256", "HS384", "HS512"}, sha512.New()))
mux.Handle("/test/sub", JWTInterceptor("test", hello(), "secret", []string{"HS256", "HS384", "HS512"}, sha512.New()))
srv := &http.Server{
Handler: mux,
Addr: ":7788",
Expand All @@ -36,9 +36,10 @@ func TestMain(m *testing.M) {
}

func TestHandlerGetBase(t *testing.T) {
tr, err := NewJWTTransport(nil,
tr, err := NewJWTTransport(
"test",
nil,
sha512.New(),
"/test",
"secret",
"HS512", 30*time.Second)
if err != nil {
Expand All @@ -63,9 +64,10 @@ func TestHandlerGetBase(t *testing.T) {
}

func TestHandlerGetParam(t *testing.T) {
tr, err := NewJWTTransport(nil,
tr, err := NewJWTTransport(
"test",
nil,
sha512.New(),
"/test",
"secret",
"HS512", 30*time.Second)
if err != nil {
Expand All @@ -91,9 +93,10 @@ func TestHandlerGetParam(t *testing.T) {
}

func TestHandlerPostParam(t *testing.T) {
tr, err := NewJWTTransport(nil,
tr, err := NewJWTTransport(
"test",
nil,
sha512.New(),
"/test",
"secret",
"HS512", 30*time.Second)
if err != nil {
Expand Down
23 changes: 13 additions & 10 deletions pkg/JWTInterceptor/transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,31 +15,33 @@ import (

type RoundTripper struct {
http.RoundTripper
service string
hash hash.Hash
hashLock sync.Mutex
ignorePrefix string
jwtKey string
jwtSigningMethod jwt.SigningMethod
lifetime time.Duration
}

type Claims struct {
Checksum string `json:"checksum"`
Service string `json:"service"`
jwt.StandardClaims
}

func NewJWTTransport(originalTransport http.RoundTripper,
func NewJWTTransport(
service string,
originalTransport http.RoundTripper,
h hash.Hash,
ignorePrefix string,
jwtKey string, jwtAlg string,
lifetime time.Duration) (http.RoundTripper, error) {
if originalTransport == nil {
originalTransport = http.DefaultTransport
}
tr := &RoundTripper{
RoundTripper: originalTransport,
service: service,
hash: h,
ignorePrefix: ignorePrefix,
jwtKey: jwtKey,
jwtSigningMethod: nil,
lifetime: lifetime,
Expand All @@ -57,18 +59,18 @@ func NewJWTTransport(originalTransport http.RoundTripper,
return tr, nil
}

func (t *RoundTripper) buildHash(req *http.Request, data []byte) ([]byte, error) {
func (t *RoundTripper) buildHashSecure(req *http.Request, data []byte) ([]byte, error) {
t.hashLock.Lock()
defer t.hashLock.Unlock()
// create hash value
t.hash.Reset()
// checksum from method + path + url query params + body
// checksum from service + method + url query params + body
if _, err := t.hash.Write([]byte(t.service)); err != nil {
return nil, errors.Wrapf(err, "cannot write rawquery to checksum")
}
if _, err := t.hash.Write([]byte(strings.ToUpper(req.Method))); err != nil {
return nil, errors.Wrapf(err, fmt.Sprintf("cannot write method to checksum"))
}
if _, err := t.hash.Write([]byte(strings.TrimPrefix(req.URL.Path, t.ignorePrefix))); err != nil {
return nil, errors.Wrapf(err, "cannot write rawquery to checksum")
}
if _, err := t.hash.Write([]byte(checksumQueryValuesString(req.URL.Query()))); err != nil {
return nil, errors.Wrapf(err, "cannot write rawquery to checksum")
}
Expand Down Expand Up @@ -97,14 +99,15 @@ func (t *RoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
body.Close()
}

hashBytes, err := t.buildHash(req, bodyBytes)
hashBytes, err := t.buildHashSecure(req, bodyBytes)
if err != nil {
return nil, errors.Wrapf(err, "cannot build hash")
}

// create token
claims := &Claims{
Checksum: fmt.Sprintf("%x", hashBytes),
Service: t.service,
StandardClaims: jwt.StandardClaims{
ExpiresAt: time.Now().Add(t.lifetime).Unix(),
Issuer: "JWTInterceptor",
Expand Down

0 comments on commit f55fb41

Please sign in to comment.