Files
higress/plugins/wasm-go/extensions/hmac-auth-apisix/config/config.go

177 lines
5.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package config
import (
"encoding/json"
"errors"
"github.com/higress-group/wasm-go/pkg/log"
"github.com/tidwall/gjson"
)
// validAlgorithms allowed_algorithms 配置中允许的算法
var validAlgorithms = map[string]bool{
"hmac-sha1": true,
"hmac-sha256": true,
"hmac-sha512": true,
}
type HmacAuthConfig struct {
Consumers []Consumer `json:"consumers" yaml:"consumers"`
GlobalAuth *bool `json:"global_auth,omitempty" yaml:"global_auth,omitempty"`
AllowedAlgorithms []string `json:"allowed_algorithms,omitempty" yaml:"allowed_algorithms,omitempty"`
ClockSkew int `json:"clock_skew,omitempty" yaml:"clock_skew,omitempty"`
SignedHeaders []string `json:"signed_headers,omitempty" yaml:"signed_headers,omitempty"`
ValidateRequestBody bool `json:"validate_request_body,omitempty" yaml:"validate_request_body,omitempty"`
HideCredentials bool `json:"hide_credentials,omitempty" yaml:"hide_credentials,omitempty"`
AnonymousConsumer string `json:"anonymous_consumer,omitempty" yaml:"anonymous_consumer,omitempty"`
Allow []string `json:"allow,omitempty" yaml:"allow,omitempty"`
// RuleSet 插件是否至少在一个 domain 或 route 上生效
RuleSet bool `json:"-" yaml:"-"`
}
type Consumer struct {
Name string `json:"name,omitempty" yaml:"name,omitempty"`
AccessKey string `json:"access_key" yaml:"access_key"`
SecretKey string `json:"secret_key" yaml:"secret_key"`
}
func ParseGlobalConfig(jsonData gjson.Result, global *HmacAuthConfig) error {
log.Debug("global config")
global.RuleSet = false
// 处理 consumers 配置
consumers := jsonData.Get("consumers")
if !consumers.Exists() {
return errors.New("consumers is required")
}
if len(consumers.Array()) == 0 {
return errors.New("consumers cannot be empty")
}
accessKeyMap := make(map[string]string)
for _, item := range consumers.Array() {
ak := item.Get("access_key")
if !ak.Exists() || ak.String() == "" {
return errors.New("consumer access_key is required")
}
sk := item.Get("secret_key")
if !sk.Exists() || sk.String() == "" {
return errors.New("consumer secret_key is required")
}
if _, ok := accessKeyMap[ak.String()]; ok {
return errors.New("duplicate consumer access_key: " + ak.String())
}
consumer := Consumer{
AccessKey: ak.String(),
SecretKey: sk.String(),
}
name := item.Get("name")
if name.Exists() && name.String() != "" {
consumer.Name = name.String()
} else {
// 如果没有提供 name则使用 access_key 作为 name
consumer.Name = ak.String()
}
global.Consumers = append(global.Consumers, consumer)
accessKeyMap[ak.String()] = ak.String()
}
// 处理 global_auth 配置
globalAuth := jsonData.Get("global_auth")
if globalAuth.Exists() {
ga := globalAuth.Bool()
global.GlobalAuth = &ga
}
// 处理 allowed_algorithms 配置
allowedAlgorithms := jsonData.Get("allowed_algorithms")
if allowedAlgorithms.Exists() && len(allowedAlgorithms.Array()) > 0 {
global.AllowedAlgorithms = []string{}
for _, item := range allowedAlgorithms.Array() {
algorithm := item.String()
if !validAlgorithms[algorithm] {
return errors.New("invalid allowed_algorithm: " + algorithm + ". Must be one of: hmac-sha1, hmac-sha256, hmac-sha512")
}
global.AllowedAlgorithms = append(global.AllowedAlgorithms, algorithm)
}
} else {
// 如果未设置,则使用默认值
global.AllowedAlgorithms = []string{"hmac-sha1", "hmac-sha256", "hmac-sha512"}
}
// 处理 clock_skew 配置
clockSkew := jsonData.Get("clock_skew")
if !clockSkew.Exists() {
// 如果未设置则使用默认值300
global.ClockSkew = 300
} else if clockSkew.Int() >= 1 {
global.ClockSkew = int(clockSkew.Int())
}
// 处理 signed_headers 配置
signedHeaders := jsonData.Get("signed_headers")
if signedHeaders.Exists() {
global.SignedHeaders = []string{}
for _, item := range signedHeaders.Array() {
global.SignedHeaders = append(global.SignedHeaders, item.String())
}
}
// 处理 validate_request_body 配置
validateRequestBody := jsonData.Get("validate_request_body")
if validateRequestBody.Exists() {
global.ValidateRequestBody = validateRequestBody.Bool()
}
// 处理 hide_credentials 配置
hideCredentials := jsonData.Get("hide_credentials")
if hideCredentials.Exists() {
global.HideCredentials = hideCredentials.Bool()
}
// 处理 anonymous_consumer 配置
anonymousConsumer := jsonData.Get("anonymous_consumer")
if anonymousConsumer.Exists() {
global.AnonymousConsumer = anonymousConsumer.String()
}
if globalBytes, err := json.Marshal(global); err == nil {
log.Debugf("global: %s", string(globalBytes))
}
return nil
}
func ParseOverrideRuleConfig(jsonData gjson.Result, global HmacAuthConfig, config *HmacAuthConfig) error {
log.Debug("domain/route config")
*config = global
// 处理 allow 配置
allow := jsonData.Get("allow")
if allow.Exists() {
config.Allow = []string{}
consumerNames := make(map[string]bool)
for _, consumer := range config.Consumers {
consumerNames[consumer.Name] = true
}
for _, item := range allow.Array() {
allowedName := item.String()
config.Allow = append(config.Allow, allowedName)
// 检查允许的名称是否在消费者列表中
if !consumerNames[allowedName] {
log.Warnf("allowed consumer name '%s' is not in the consumers list", allowedName)
}
}
}
config.RuleSet = true
if configBytes, err := json.Marshal(config); err == nil {
log.Debugf("config: %s", string(configBytes))
}
return nil
}