package plugin import ( "crypto/rsa" "encoding/base64" "errors" "fmt" "net/url" "sort" "strings" "time" "github.com/golang-jwt/jwt/v5" ) // 基本认证签名器 func makeBasicAuthSign(req *Request, cfg *SignerConfig) error { // 1. 获取用户名和密码 username := cfg.String("username", "") password := cfg.String("password", "") // 2. 构造认证字符串 auth := username + ":" + password encoded := base64.StdEncoding.EncodeToString([]byte(auth)) // 3. 添加认证头 req.Headers["Authorization"] = "Basic " + encoded return nil } // Bearer Token认证 func makeBearerSign(req *Request, cfg *SignerConfig) error { req.Headers["Authorization"] = "Bearer " + cfg.String("key", "") return nil } // 通用JWT签名器 func makeJWTSign(req *Request, cfg *SignerConfig) error { // 1. 获取JWT配置 secret := cfg.String("secret", "") algorithm := cfg.String("algorithm", "HS256") expires := cfg.Int("expires", 3600) // 默认1小时有效期 timeuint := cfg.String("timeuint", "s") // 时间戳单位 // 2. 创建Claims var tm, exp int64 if timeuint == "ms" { tm = time.Now().UnixMilli() exp = tm + expires*1000 } else { tm = time.Now().Unix() exp = tm + expires } claims := jwt.MapClaims{ "exp": exp, "iat": tm, } // 3. 添加自定义声明 for k, v := range cfg.Map("claims") { if v == "{{timestamp}}" { claims[k] = tm } else { claims[k] = v } } // fmt.Println(u.BMagenta(u.JsonP(claims)), algorithm) // 4. 创建Token var token *jwt.Token switch algorithm { case "HS256": token = jwt.NewWithClaims(jwt.SigningMethodHS256, claims) case "HS384": token = jwt.NewWithClaims(jwt.SigningMethodHS384, claims) case "HS512": token = jwt.NewWithClaims(jwt.SigningMethodHS512, claims) case "RS256": token = jwt.NewWithClaims(jwt.SigningMethodRS256, claims) default: // 默认使用HS256 token = jwt.NewWithClaims(jwt.SigningMethodHS256, claims) } token.Header["alg"] = algorithm for k, v := range cfg.Map("jwtHeader") { token.Header[k] = v } // fmt.Println(u.BYellow(u.JsonP(token.Header)), "===") // 5. 签名Token var signedString string var err error if strings.HasPrefix(algorithm, "HS") { signedString, err = token.SignedString([]byte(secret)) } else if strings.HasPrefix(algorithm, "RS") { // 处理RSA私钥 if privateKey := cfg.String("privateKey", ""); privateKey != "" { var prikey *rsa.PrivateKey prikey, err = jwt.ParseRSAPrivateKeyFromPEM([]byte(privateKey)) if err == nil { signedString, err = token.SignedString(prikey) } } else { err = errors.New("privateKey is empty") } } if err != nil { // 处理错误 return err } // 6. 添加认证头 prefix := cfg.String("prefix", "Bearer ") req.Headers["Authorization"] = prefix + signedString return nil } // // 通用HMAC-SHA256签名器 // func makeHmacSign(req *Request, cfg *SignerConfig) error { // hashMethod := strings.ToUpper(cfg.String("hashMethod", "SHA256")) // // 1. 获取待签名数据 // dataToSign := cfg.String("signData", "") // if dataToSign == "" { // // 默认使用HTTP方法+URL+当前时间戳 // timestamp := time.Now().Format(time.RFC3339) // dataToSign = req.Method + " " + req.Url + "\n" + timestamp // cfg.Set("timestamp", timestamp) // } // // 2. 计算签名 // key := []byte(cfg.String("secret", "")) // var h hash.Hash // switch hashMethod { // case "SHA1": // h = hmac.New(sha1.New, key) // case "SHA256": // h = hmac.New(sha256.New, key) // case "SHA384": // h = hmac.New(sha512.New384, key) // case "SHA512": // h = hmac.New(sha512.New, key) // default: // h = hmac.New(sha256.New, key) // } // h.Write([]byte(dataToSign)) // signature := base64.StdEncoding.EncodeToString(h.Sum(nil)) // // 3. 添加到请求 // headerName := cfg.String("headerName", "X-Signature") // req.Headers[headerName] = signature // // 4. 可选: 添加时间戳 // timestamp := cfg.String("timestamp", "") // if timestamp != "" { // tsHeader := cfg.String("tsHeader", "X-Timestamp") // req.Headers[tsHeader] = timestamp // } // return nil // } func SortParams(params map[string]string, allow *[]string, deny *[]string) (paramsList string, paramsPairs string) { if len(params) == 0 { return "", "" } // 获取排序的key keys := make([]string, 0) for k := range params { // 按白名单过滤 if allow != nil { isAllow := false for _, a := range *allow { if a == k || (strings.HasSuffix(a, "*") && strings.HasPrefix(k, a[:len(a)-1])) { isAllow = true } } if !isAllow { continue } } // 按黑名单过滤 if deny != nil { isDeny := false for _, d := range *deny { if d == k || (strings.HasSuffix(d, "*") && strings.HasPrefix(k, d[:len(d)-1])) { isDeny = true } } if isDeny { continue } } keys = append(keys, k) } sort.Strings(keys) // 构建urlParamList和httpParameters paramList := make([]string, 0, len(keys)) paramPairs := make([]string, 0, len(keys)) for _, k := range keys { paramList = append(paramList, strings.ToLower(url.QueryEscape(k))) paramPairs = append(paramPairs, fmt.Sprintf("%s=%s", strings.ToLower(url.QueryEscape(k)), url.QueryEscape(params[k]))) } return strings.Join(paramList, ";"), strings.Join(paramPairs, "&") }