Skip to content

Commit

Permalink
R4R: add jwt to tss node rpc (#854)
Browse files Browse the repository at this point in the history
* add jwt to tss node rpc

* simplify code

* add jwt token to tss manager and tss node

* improve jwt error code

* bugfix

* remove useless code

* remove useless code

* go mod tidy tss go.sum
  • Loading branch information
HaoyangLiu authored Jun 19, 2023
1 parent ab8293f commit f401e20
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 12 deletions.
4 changes: 3 additions & 1 deletion tss/common/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,14 @@ type Configuration struct {
TimedTaskInterval string `json:"timed_task_interval" mapstructure:"timed_task_interval"`
L1ReceiptConfirmTimeout string `json:"l1_receipt_confirm_timeout" mapstructure:"l1_receipt_confirm_timeout"`
L1ConfirmBlocks int `json:"l1_confirm_blocks" mapstructure:"l1_confirm_blocks"`
L1StartBlockNumber string `json:"l1_start_block_number" mapstructure:"l1_start_block_number"`
L1StartBlockNumber string `json:"l1_start_block_number" mapstructure:"l1_start_block_number"`
MissSignedNumber int `json:"miss_signed_number" mapstructure:"miss_signed_number"`
}

type ManagerConfig struct {
WsAddr string `json:"ws_addr" mapstructure:"ws_addr"`
HttpAddr string `json:"http_addr" mapstructure:"http_addr"`
JwtSecret string `json:"jwt_secret" mapstructure:"jwt_secret"`
DBDir string `json:"db_dir" mapstructure:"db_dir"`
PrivateKey string `json:"private_key" mapstructure:"private_key"`

Expand All @@ -43,6 +44,7 @@ type NodeConfig struct {
DBDir string `json:"db_dir" mapstructure:"db_dir"`
WsAddr string `json:"ws_addr" mapstructure:"ws_addr"`
HttpAddr string `json:"http_addr" mapstructure:"http_addr"`
JwtSecret string `json:"jwt_secret" mapstructure:"jwt_secret"`
L2EthRpc string `json:"l2_eth_rpc" mapstructure:"l2_eth_rpc"`
DisableHTTP2 bool `json:"disable_http2" mapstructure:"disable_http2"`
PrivateKey string `json:"private_key" mapstructure:"private_key"`
Expand Down
66 changes: 66 additions & 0 deletions tss/common/jwthandle.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package common

import (
"net/http"
"strings"
"time"

"github.com/golang-jwt/jwt/v4"
)

const (
jwtExpiryTimeout = 60 * time.Second
)

type JwtHandler struct {
keyFunc func(token *jwt.Token) (interface{}, error)
handler http.Handler
}

func NewJwtHandler(handle http.Handler, jetSecretKey string) (http.Handler, error) {
jwtHandler := &JwtHandler{
keyFunc: func(token *jwt.Token) (interface{}, error) {
return []byte(jetSecretKey), nil
},
handler: handle,
}
return jwtHandler, nil
}

// ServeHTTP implements http.Handler
func (handler *JwtHandler) ServeHTTP(out http.ResponseWriter, r *http.Request) {
var (
strToken string
claims jwt.RegisteredClaims
)
if auth := r.Header.Get("Authorization"); strings.HasPrefix(auth, "Bearer ") {
strToken = strings.TrimPrefix(auth, "Bearer ")
}
if len(strToken) == 0 {
http.Error(out, "missing token", http.StatusUnauthorized)
return
}
// We explicitly set only HS256 allowed, and also disables the
// claim-check: the RegisteredClaims internally requires 'iat' to
// be no later than 'now', but we allow for a bit of drift.
token, err := jwt.ParseWithClaims(strToken, &claims, handler.keyFunc,
jwt.WithValidMethods([]string{"HS256"}),
jwt.WithoutClaimsValidation())

switch {
case err != nil:
http.Error(out, err.Error(), http.StatusUnauthorized)
case !token.Valid:
http.Error(out, "invalid token", http.StatusUnauthorized)
case !claims.VerifyExpiresAt(time.Now(), false): // optional
http.Error(out, "token is expired", http.StatusUnauthorized)
case claims.IssuedAt == nil:
http.Error(out, "missing issued-at", http.StatusUnauthorized)
case time.Since(claims.IssuedAt.Time) > jwtExpiryTimeout:
http.Error(out, "stale token", http.StatusUnauthorized)
case time.Until(claims.IssuedAt.Time) > jwtExpiryTimeout:
http.Error(out, "future token", http.StatusUnauthorized)
default:
handler.handler.ServeHTTP(out, r)
}
}
1 change: 1 addition & 0 deletions tss/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ require (
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect
github.com/godbus/dbus/v5 v5.1.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-jwt/jwt/v4 v4.5.0
github.com/golang/mock v1.6.0 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/golang/snappy v0.0.4 // indirect
Expand Down
2 changes: 2 additions & 0 deletions tss/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,7 @@ github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG
github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA=
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
Expand Down Expand Up @@ -372,6 +373,7 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
Expand Down
16 changes: 15 additions & 1 deletion tss/manager/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,20 @@ import (
"github.com/gin-gonic/gin"
"github.com/mantlenetworkio/mantle/l2geth/log"
"github.com/mantlenetworkio/mantle/tss/common"
"github.com/mantlenetworkio/mantle/tss/index"
"github.com/mantlenetworkio/mantle/tss/manager/l1chain"
"github.com/mantlenetworkio/mantle/tss/manager/router"
"github.com/mantlenetworkio/mantle/tss/manager/store"
"github.com/mantlenetworkio/mantle/tss/slash"
"github.com/mantlenetworkio/mantle/tss/ws/server"
"github.com/spf13/cobra"
)

const (
jwtExpiryTimeout = 60 * time.Second
jwtKeyLength = 32
)

func Command() *cobra.Command {
cmd := &cobra.Command{
Use: "manager",
Expand Down Expand Up @@ -74,10 +83,15 @@ func run(cmd *cobra.Command) error {
r := gin.Default()
registry.Register(r)

jwtHandler, err := common.NewJwtHandler(r, config.Manager.JwtSecret)
if err != nil {
return err
}

// custom http configuration
s := &http.Server{
Addr: config.Manager.HttpAddr,
Handler: r,
Handler: jwtHandler,
}
go func() {
if err := s.ListenAndServe(); err != nil && errors.Is(err, http.ErrServerClosed) {
Expand Down
6 changes: 5 additions & 1 deletion tss/node/cmd/tssnode/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,11 @@ func runNode(cmd *cobra.Command) error {
}
signer.Start()

hs := server.NewHttpServer(cfg.Node.HttpAddr, tssInstance, signer, nonProd)
hs, err := server.NewHttpServer(cfg.Node.HttpAddr, tssInstance, signer, nonProd, cfg.Node.JwtSecret)
if err != nil {
log.Error().Err(err).Msg("fail to create http server")
return err
}

if err := hs.Start(); err != nil {
log.Error().Err(err).Msg("fail to start http server")
Expand Down
24 changes: 15 additions & 9 deletions tss/node/server/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,18 @@ import (
"encoding/hex"
"encoding/json"
"errors"
sign "github.com/mantlenetworkio/mantle/tss/node/signer"
"github.com/mantlenetworkio/mantle/tss/node/tsslib/keysign"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"net/http"
"time"

"github.com/gorilla/mux"
cmm "github.com/mantlenetworkio/mantle/tss/common"
sign "github.com/mantlenetworkio/mantle/tss/node/signer"
"github.com/mantlenetworkio/mantle/tss/node/tsslib"
"github.com/mantlenetworkio/mantle/tss/node/tsslib/common"
"github.com/mantlenetworkio/mantle/tss/node/tsslib/keygen"
"github.com/mantlenetworkio/mantle/tss/node/tsslib/keysign"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
)
Expand All @@ -36,19 +37,23 @@ type GenRequest struct {
type MockEventRequest struct {
}

func NewHttpServer(addr string, t tsslib.Server, signer *sign.Processor, nonProd bool) *Server {
func NewHttpServer(addr string, t tsslib.Server, signer *sign.Processor, nonProd bool, jwtSecretStr string) (*Server, error) {
hs := &Server{
logger: log.With().Str("module", "http").Logger(),
tssServer: t,
nonProd: nonProd,
signer: signer,
}
handler, err := hs.newHandler(jwtSecretStr)
if err != nil {
return nil, err
}
s := &http.Server{
Addr: addr,
Handler: hs.newHandler(),
Handler: handler,
}
hs.s = s
return hs
return hs, nil
}

func (hs *Server) Start() error {
Expand All @@ -71,7 +76,7 @@ func (hs *Server) Stop() {
}
}

func (hs *Server) newHandler() http.Handler {
func (hs *Server) newHandler(jwtSecretStr string) (http.Handler, error) {
router := mux.NewRouter()
router.Handle("/ping", http.HandlerFunc(hs.pingHandler)).Methods(http.MethodGet)
router.Handle("/gen-key", http.HandlerFunc(hs.keyGenHandler)).Methods(http.MethodPost)
Expand All @@ -84,7 +89,8 @@ func (hs *Server) newHandler() http.Handler {
))

router.Use(logMiddleware())
return router

return cmm.NewJwtHandler(router, jwtSecretStr)
}

func logMiddleware() mux.MiddlewareFunc {
Expand Down

0 comments on commit f401e20

Please sign in to comment.