feat: add unified authorization middleware
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
ftsService "bsm/full/module/base/fts/service"
|
||||
mgtService "bsm/full/module/base/mgt/service"
|
||||
@@ -11,24 +12,26 @@ import (
|
||||
senderService "bsm/full/module/base/sender/service"
|
||||
walletService "bsm/full/module/finance/wallet/service"
|
||||
"git.apinb.com/bsm-sdk/core/conf"
|
||||
"git.apinb.com/bsm-sdk/core/env"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
coreVars "git.apinb.com/bsm-sdk/core/vars"
|
||||
)
|
||||
|
||||
type SrvConfig struct {
|
||||
conf.Base `yaml:",inline"`
|
||||
Server ServerConfig `yaml:"Server"`
|
||||
DynamicRPC DynamicRPCConfig `yaml:"DynamicRPC"`
|
||||
Databases *conf.DBConf `yaml:"Databases"`
|
||||
MicroService *conf.MicroServiceConf `yaml:"MicroService"`
|
||||
Rpc map[string]conf.RpcConf `yaml:"Rpc"`
|
||||
Apm *conf.ApmConf `yaml:"APM"`
|
||||
Etcd *conf.EtcdConf `yaml:"Etcd"`
|
||||
Services []string `yaml:"Services"`
|
||||
Fts *ftsService.Config `yaml:"Fts"`
|
||||
Mgt *mgtService.Config `yaml:"Mgt"`
|
||||
Passport *passportService.Config `yaml:"Passport"`
|
||||
Sender *senderService.Config `yaml:"Sender"`
|
||||
Wallet *walletService.Config `yaml:"Wallet"`
|
||||
conf.Base `yaml:",inline"`
|
||||
Server ServerConfig `yaml:"Server"`
|
||||
Authorization AuthorizationConfig `yaml:"Authorization"`
|
||||
Databases *conf.DBConf `yaml:"Databases"`
|
||||
MicroService *conf.MicroServiceConf `yaml:"MicroService"`
|
||||
Rpc map[string]conf.RpcConf `yaml:"Rpc"`
|
||||
Apm *conf.ApmConf `yaml:"APM"`
|
||||
Etcd *conf.EtcdConf `yaml:"Etcd"`
|
||||
Services []string `yaml:"Services"`
|
||||
Fts *ftsService.Config `yaml:"Fts"`
|
||||
Mgt *mgtService.Config `yaml:"Mgt"`
|
||||
Passport *passportService.Config `yaml:"Passport"`
|
||||
Sender *senderService.Config `yaml:"Sender"`
|
||||
Wallet *walletService.Config `yaml:"Wallet"`
|
||||
}
|
||||
|
||||
type ListenerConfig struct {
|
||||
@@ -42,8 +45,10 @@ type ServerConfig struct {
|
||||
HTTP ListenerConfig `yaml:"HTTP"`
|
||||
}
|
||||
|
||||
type DynamicRPCConfig struct {
|
||||
Allow []string `yaml:"Allow"`
|
||||
type AuthorizationConfig struct {
|
||||
Key string `yaml:"Key"`
|
||||
Expire int64 `yaml:"Expire"`
|
||||
Anonymous []string `yaml:"Anonymous"`
|
||||
}
|
||||
|
||||
var Spec SrvConfig
|
||||
@@ -55,6 +60,18 @@ func New(serviceKey string) {
|
||||
if Spec.Server.GRPC.Addr == Spec.Server.HTTP.Addr {
|
||||
panic("gRPC and HTTP listeners must use different addresses")
|
||||
}
|
||||
if strings.TrimSpace(Spec.Authorization.Key) == "" {
|
||||
panic("Authorization.Key must not be empty")
|
||||
}
|
||||
keyLength := len(Spec.Authorization.Key)
|
||||
if keyLength != 16 && keyLength != 24 && keyLength != 32 {
|
||||
panic("Authorization.Key must contain 16, 24, or 32 bytes")
|
||||
}
|
||||
if Spec.Authorization.Expire <= 0 {
|
||||
panic("Authorization.Expire must be greater than zero")
|
||||
}
|
||||
env.NewEnv().JwtSecretKey = Spec.Authorization.Key
|
||||
coreVars.JwtExpire = time.Duration(Spec.Authorization.Expire) * time.Second
|
||||
// Keep the embedded base address meaningful for module configurations that
|
||||
// still consume it, while all itself uses the two explicit listeners.
|
||||
Spec.BindIP, Spec.Port, Spec.Addr = Spec.Server.HTTP.BindIP, Spec.Server.HTTP.Port, Spec.Server.HTTP.Addr
|
||||
|
||||
@@ -23,8 +23,12 @@ func TestAllDevConfig(t *testing.T) {
|
||||
if cfg.Server.GRPC.Port == "" || cfg.Server.HTTP.Port == "" || cfg.Server.GRPC.Port == cfg.Server.HTTP.Port {
|
||||
t.Fatal("separate gRPC and HTTP ports are required")
|
||||
}
|
||||
if len(cfg.DynamicRPC.Allow) == 0 {
|
||||
t.Fatal("dynamic RPC allow list must be explicit")
|
||||
if cfg.Authorization.Key == "" || cfg.Authorization.Expire <= 0 {
|
||||
t.Fatal("authorization key and expiration are required")
|
||||
}
|
||||
keyLength := len(cfg.Authorization.Key)
|
||||
if keyLength != 16 && keyLength != 24 && keyLength != 32 {
|
||||
t.Fatal("authorization key must be compatible with the JWT issuer")
|
||||
}
|
||||
if cfg.Fts == nil || cfg.Mgt == nil || cfg.Passport == nil || cfg.Sender == nil || cfg.Wallet == nil {
|
||||
t.Fatal("service-specific configuration is incomplete")
|
||||
|
||||
Reference in New Issue
Block a user