add authorizing fileId write access

need to secure upload/update/delete for benchmark/filer/mount
need to add secure grpc
This commit is contained in:
Chris Lu
2019-02-14 00:08:20 -08:00
parent 4ff4a147b2
commit 215cd27b37
8 changed files with 125 additions and 92 deletions

View File

@@ -41,21 +41,21 @@ https://github.com/pkieltyka/jwtauth/blob/master/jwtauth.go
*/
type Guard struct {
whiteList []string
SecretKey SigningKey
whiteList []string
SigningKey SigningKey
isActive bool
}
func NewGuard(whiteList []string, secretKey string) *Guard {
g := &Guard{whiteList: whiteList, SecretKey: SigningKey(secretKey)}
g.isActive = len(g.whiteList) != 0 || len(g.SecretKey) != 0
func NewGuard(whiteList []string, signingKey string) *Guard {
g := &Guard{whiteList: whiteList, SigningKey: SigningKey(signingKey)}
g.isActive = len(g.whiteList) != 0 || len(g.SigningKey) != 0
return g
}
func (g *Guard) WhiteList(f func(w http.ResponseWriter, r *http.Request)) func(w http.ResponseWriter, r *http.Request) {
if !g.isActive {
//if no security needed, just skip all checkings
//if no security needed, just skip all checking
return f
}
return func(w http.ResponseWriter, r *http.Request) {
@@ -67,20 +67,6 @@ func (g *Guard) WhiteList(f func(w http.ResponseWriter, r *http.Request)) func(w
}
}
func (g *Guard) Secure(f func(w http.ResponseWriter, r *http.Request)) func(w http.ResponseWriter, r *http.Request) {
if !g.isActive {
//if no security needed, just skip all checkings
return f
}
return func(w http.ResponseWriter, r *http.Request) {
if err := g.checkJwt(w, r); err != nil {
w.WriteHeader(http.StatusUnauthorized)
return
}
f(w, r)
}
}
func GetActualRemoteHost(r *http.Request) (host string, err error) {
host = r.Header.Get("HTTP_X_FORWARDED_FOR")
if host == "" {
@@ -130,33 +116,3 @@ func (g *Guard) checkWhiteList(w http.ResponseWriter, r *http.Request) error {
glog.V(0).Infof("Not in whitelist: %s", r.RemoteAddr)
return fmt.Errorf("Not in whitelis: %s", r.RemoteAddr)
}
func (g *Guard) checkJwt(w http.ResponseWriter, r *http.Request) error {
if g.checkWhiteList(w, r) == nil {
return nil
}
if len(g.SecretKey) == 0 {
return nil
}
tokenStr := GetJwt(r)
if tokenStr == "" {
return ErrUnauthorized
}
// Verify the token
token, err := DecodeJwt(g.SecretKey, tokenStr)
if err != nil {
glog.V(1).Infof("Token verification error from %s: %v", r.RemoteAddr, err)
return ErrUnauthorized
}
if !token.Valid {
glog.V(1).Infof("Token invliad from %s: %v", r.RemoteAddr, tokenStr)
return ErrUnauthorized
}
glog.V(1).Infof("No permission from %s", r.RemoteAddr)
return fmt.Errorf("No write permission from %s", r.RemoteAddr)
}

View File

@@ -1,6 +1,7 @@
package security
import (
"fmt"
"net/http"
"strings"
@@ -11,21 +12,28 @@ import (
)
type EncodedJwt string
type SigningKey string
type SigningKey []byte
type SeaweedFileIdClaims struct {
Fid string `json:"fid"`
jwt.StandardClaims
}
func GenJwt(signingKey SigningKey, fileId string) EncodedJwt {
if signingKey == "" {
if len(signingKey) == 0 {
return ""
}
t := jwt.New(jwt.GetSigningMethod("HS256"))
t.Claims = &jwt.StandardClaims{
ExpiresAt: time.Now().Add(time.Second * 10).Unix(),
Subject: fileId,
claims := SeaweedFileIdClaims{
fileId,
jwt.StandardClaims{
ExpiresAt: time.Now().Add(time.Second * 10).Unix(),
},
}
encoded, e := t.SignedString(signingKey)
t := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
encoded, e := t.SignedString([]byte(signingKey))
if e != nil {
glog.V(0).Infof("Failed to sign claims: %v", t.Claims)
glog.V(0).Infof("Failed to sign claims %+v: %v", t.Claims, e)
return ""
}
return EncodedJwt(encoded)
@@ -44,31 +52,15 @@ func GetJwt(r *http.Request) EncodedJwt {
}
}
// Get token from cookie
if tokenStr == "" {
cookie, err := r.Cookie("jwt")
if err == nil {
tokenStr = cookie.Value
}
}
return EncodedJwt(tokenStr)
}
func EncodeJwt(signingKey SigningKey, claims *jwt.StandardClaims) (EncodedJwt, error) {
if signingKey == "" {
return "", nil
}
t := jwt.New(jwt.GetSigningMethod("HS256"))
t.Claims = claims
encoded, e := t.SignedString(signingKey)
return EncodedJwt(encoded), e
}
func DecodeJwt(signingKey SigningKey, tokenString EncodedJwt) (token *jwt.Token, err error) {
// check exp, nbf
return jwt.Parse(string(tokenString), func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("unknown token method")
}
return signingKey, nil
})
}