github.com/weedge/lib@v0.0.0-20230424045628-a36dcc1d90e4/client/mq/kafka/auth/options.go (about) 1 package auth 2 3 import ( 4 "crypto/tls" 5 "crypto/x509" 6 "io/ioutil" 7 8 "github.com/weedge/lib/container/slice" 9 "github.com/weedge/lib/log" 10 11 "github.com/Shopify/sarama" 12 ) 13 14 type AuthOptions struct { 15 // security-protocol: SSL (broker service config default PLAINTEXT, need security.inter.broker.protocol=SSL) 16 enableSSL bool 17 certFile string // the optional certificate file for client authentication 18 keyFile string // the optional key file for client authentication 19 caFile string // the optional certificate authority file for TLS client authentication 20 verifySSL bool // the optional verify ssl certificates chain 21 22 //SASL: PLAINTEXT(Kafka 0.10.0.0+), SCRAM(kafka 0.10.2.0+ dynamic add user), OAUTHBEARER(Kafka2.0.0+,JWT) 23 enableSASL bool 24 authentication string // PLAINTEXT,SCRAM,OAUTHBEARER,if enableSASL true,default SCRAM 25 saslUser string // The SASL username 26 saslPassword string // The SASL password 27 scramAlgorithm string // The SASL SCRAM SHA algorithm sha256 or sha512 as mechanism 28 } 29 30 type Option interface { 31 apply(o *AuthOptions) 32 } 33 34 type funcServerOption struct { 35 f func(o *AuthOptions) 36 } 37 38 func (fdo *funcServerOption) apply(o *AuthOptions) { 39 fdo.f(o) 40 } 41 42 func newFuncServerOption(f func(o *AuthOptions)) *funcServerOption { 43 return &funcServerOption{ 44 f: f, 45 } 46 } 47 48 func WithEnableSSL(enableSSL bool) Option { 49 return newFuncServerOption(func(o *AuthOptions) { 50 o.enableSSL = enableSSL 51 }) 52 } 53 54 func WithSSLCertFile(certFile string) Option { 55 return newFuncServerOption(func(o *AuthOptions) { 56 o.certFile = certFile 57 }) 58 } 59 60 func WithSSLKeyFile(keyFile string) Option { 61 return newFuncServerOption(func(o *AuthOptions) { 62 o.keyFile = keyFile 63 }) 64 } 65 66 func WithSSLCaFile(caFile string) Option { 67 return newFuncServerOption(func(o *AuthOptions) { 68 o.caFile = caFile 69 }) 70 } 71 72 func (opts *AuthOptions) InitSSL(config *sarama.Config) { 73 if opts.enableSSL == false { 74 return 75 } 76 77 tlsConfig := opts.CreateTlsConfiguration() 78 if tlsConfig != nil { 79 config.Net.TLS.Config = tlsConfig 80 config.Net.TLS.Enable = true 81 } 82 } 83 84 func (opts *AuthOptions) CreateTlsConfiguration() (t *tls.Config) { 85 if opts.certFile == "" || opts.keyFile == "" || opts.caFile == "" { 86 return 87 } 88 89 cert, err := tls.LoadX509KeyPair(opts.certFile, opts.keyFile) 90 if err != nil { 91 log.Error("tls.LoadX509KeyPair err", err) 92 return 93 } 94 95 caCert, err := ioutil.ReadFile(opts.caFile) 96 if err != nil { 97 log.Error("ioutil.ReadFile err", err) 98 return 99 } 100 101 caCertPool := x509.NewCertPool() 102 caCertPool.AppendCertsFromPEM(caCert) 103 104 t = &tls.Config{ 105 Certificates: []tls.Certificate{cert}, 106 RootCAs: caCertPool, 107 InsecureSkipVerify: opts.verifySSL, 108 } 109 110 return 111 } 112 113 func WithEnableSASL(enableSASL bool) Option { 114 return newFuncServerOption(func(o *AuthOptions) { 115 o.enableSASL = enableSASL 116 }) 117 } 118 119 func WithAuthentication(authentication string) Option { 120 return newFuncServerOption(func(o *AuthOptions) { 121 o.authentication = "SCRAM" 122 if slice.Contains([]string{"PLAINTEXT", "SCRAM", "OAUTHBEARER"}, authentication) { 123 o.authentication = authentication 124 } 125 }) 126 } 127 128 func WithScramAlgorithm(scramAlgorithm string) Option { 129 return newFuncServerOption(func(o *AuthOptions) { 130 o.scramAlgorithm = "sha256" 131 if slice.Contains([]string{"sha256", "sha512"}, scramAlgorithm) { 132 o.scramAlgorithm = scramAlgorithm 133 } 134 }) 135 } 136 137 func WithSASLUser(saslUser string) Option { 138 return newFuncServerOption(func(o *AuthOptions) { 139 o.saslUser = saslUser 140 }) 141 } 142 143 func WithSASLPassword(saslPassword string) Option { 144 return newFuncServerOption(func(o *AuthOptions) { 145 o.saslPassword = saslPassword 146 }) 147 } 148 149 func (opts *AuthOptions) InitSASLSCRAM(conf *sarama.Config) { 150 if !opts.enableSASL { 151 return 152 } 153 if opts.authentication != "SCRAM" { 154 return 155 } 156 conf.Net.SASL.Enable = opts.enableSASL 157 conf.Net.SASL.User = opts.saslUser 158 conf.Net.SASL.Password = opts.saslPassword 159 conf.Net.SASL.Handshake = true 160 switch opts.scramAlgorithm { 161 case "sha512": 162 conf.Net.SASL.SCRAMClientGeneratorFunc = func() sarama.SCRAMClient { return &XDGSCRAMClient{HashGeneratorFcn: SHA512} } 163 conf.Net.SASL.Mechanism = sarama.SASLTypeSCRAMSHA512 164 case "sha256": 165 fallthrough 166 default: 167 conf.Net.SASL.SCRAMClientGeneratorFunc = func() sarama.SCRAMClient { return &XDGSCRAMClient{HashGeneratorFcn: SHA256} } 168 conf.Net.SASL.Mechanism = sarama.SASLTypeSCRAMSHA256 169 } 170 } 171 172 func GetAuthOptions(opts ...Option) *AuthOptions { 173 authOptions := &AuthOptions{ 174 enableSSL: false, 175 certFile: "", 176 keyFile: "", 177 caFile: "", 178 verifySSL: false, 179 180 enableSASL: false, 181 authentication: "SCRAM", 182 saslUser: "", 183 saslPassword: "", 184 scramAlgorithm: "sha256", 185 } 186 187 for _, o := range opts { 188 o.apply(authOptions) 189 } 190 191 return authOptions 192 }