Skip to content

Commit 2cb3c1c

Browse files
ItalyPaleAleAbhinav Mishra
andauthored
Enhance Kafka pubsub OIDC auth support to support oauthbearer.extensions (#3124)
Signed-off-by: ItalyPaleAle <[email protected]> Co-authored-by: Abhinav Mishra <[email protected]>
1 parent 304ad6b commit 2cb3c1c

File tree

5 files changed

+57
-31
lines changed

5 files changed

+57
-31
lines changed

bindings/kafka/metadata.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ authenticationProfiles:
5454
Although not required, this field is recommended.
5555
example: '"openid,kafka-prod"'
5656
default: '"openid"'
57+
- name: oidcExtensions
58+
description: |
59+
String containing a JSON-encoded dictionary of OAuth2/OIDC extensions to request with the access token.
60+
example: |
61+
{"cluster":"kafka","poolid":"kafkapool"}
62+
type: string
5763
- title: "SASL Authentication"
5864
description: |
5965
Authenticate using SASL.

internal/component/kafka/auth.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ func updateTLSConfig(config *sarama.Config, metadata *KafkaMetadata) error {
7373
}
7474

7575
func updateOidcAuthInfo(config *sarama.Config, metadata *KafkaMetadata) error {
76-
tokenProvider := newOAuthTokenSource(metadata.OidcTokenEndpoint, metadata.OidcClientID, metadata.OidcClientSecret, metadata.internalOidcScopes)
76+
tokenProvider := metadata.getOAuthTokenSource()
7777

7878
if metadata.TLSCaCert != "" {
7979
err := tokenProvider.addCa(metadata.TLSCaCert)
@@ -82,11 +82,9 @@ func updateOidcAuthInfo(config *sarama.Config, metadata *KafkaMetadata) error {
8282
}
8383
}
8484

85-
tokenProvider.skipCaVerify = metadata.TLSSkipVerify
86-
8785
config.Net.SASL.Enable = true
8886
config.Net.SASL.Mechanism = sarama.SASLTypeOAuth
89-
config.Net.SASL.TokenProvider = &tokenProvider
87+
config.Net.SASL.TokenProvider = tokenProvider
9088

9189
return nil
9290
}

internal/component/kafka/metadata.go

Lines changed: 34 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ limitations under the License.
1414
package kafka
1515

1616
import (
17+
"encoding/json"
1718
"errors"
1819
"fmt"
1920
"strconv"
@@ -42,31 +43,33 @@ const (
4243
)
4344

4445
type KafkaMetadata struct {
45-
Brokers string `mapstructure:"brokers"`
46-
internalBrokers []string `mapstructure:"-"`
47-
ConsumerGroup string `mapstructure:"consumerGroup"`
48-
ClientID string `mapstructure:"clientId"`
49-
AuthType string `mapstructure:"authType"`
50-
SaslUsername string `mapstructure:"saslUsername"`
51-
SaslPassword string `mapstructure:"saslPassword"`
52-
SaslMechanism string `mapstructure:"saslMechanism"`
53-
InitialOffset string `mapstructure:"initialOffset"`
54-
internalInitialOffset int64 `mapstructure:"-"`
55-
MaxMessageBytes int `mapstructure:"maxMessageBytes"`
56-
OidcTokenEndpoint string `mapstructure:"oidcTokenEndpoint"`
57-
OidcClientID string `mapstructure:"oidcClientID"`
58-
OidcClientSecret string `mapstructure:"oidcClientSecret"`
59-
OidcScopes string `mapstructure:"oidcScopes"`
60-
internalOidcScopes []string `mapstructure:"-"`
61-
TLSDisable bool `mapstructure:"disableTls"`
62-
TLSSkipVerify bool `mapstructure:"skipVerify"`
63-
TLSCaCert string `mapstructure:"caCert"`
64-
TLSClientCert string `mapstructure:"clientCert"`
65-
TLSClientKey string `mapstructure:"clientKey"`
66-
ConsumeRetryEnabled bool `mapstructure:"consumeRetryEnabled"`
67-
ConsumeRetryInterval time.Duration `mapstructure:"consumeRetryInterval"`
68-
Version string `mapstructure:"version"`
69-
internalVersion sarama.KafkaVersion `mapstructure:"-"`
46+
Brokers string `mapstructure:"brokers"`
47+
internalBrokers []string `mapstructure:"-"`
48+
ConsumerGroup string `mapstructure:"consumerGroup"`
49+
ClientID string `mapstructure:"clientId"`
50+
AuthType string `mapstructure:"authType"`
51+
SaslUsername string `mapstructure:"saslUsername"`
52+
SaslPassword string `mapstructure:"saslPassword"`
53+
SaslMechanism string `mapstructure:"saslMechanism"`
54+
InitialOffset string `mapstructure:"initialOffset"`
55+
internalInitialOffset int64 `mapstructure:"-"`
56+
MaxMessageBytes int `mapstructure:"maxMessageBytes"`
57+
OidcTokenEndpoint string `mapstructure:"oidcTokenEndpoint"`
58+
OidcClientID string `mapstructure:"oidcClientID"`
59+
OidcClientSecret string `mapstructure:"oidcClientSecret"`
60+
OidcScopes string `mapstructure:"oidcScopes"`
61+
OidcExtensions string `mapstructure:"oidcExtensions"`
62+
internalOidcScopes []string `mapstructure:"-"`
63+
TLSDisable bool `mapstructure:"disableTls"`
64+
TLSSkipVerify bool `mapstructure:"skipVerify"`
65+
TLSCaCert string `mapstructure:"caCert"`
66+
TLSClientCert string `mapstructure:"clientCert"`
67+
TLSClientKey string `mapstructure:"clientKey"`
68+
ConsumeRetryEnabled bool `mapstructure:"consumeRetryEnabled"`
69+
ConsumeRetryInterval time.Duration `mapstructure:"consumeRetryInterval"`
70+
Version string `mapstructure:"version"`
71+
internalVersion sarama.KafkaVersion `mapstructure:"-"`
72+
internalOidcExtensions map[string]string `mapstructure:"-"`
7073
}
7174

7275
// upgradeMetadata updates metadata properties based on deprecated usage.
@@ -180,6 +183,12 @@ func (k *Kafka) getKafkaMetadata(meta map[string]string) (*KafkaMetadata, error)
180183
k.logger.Warn("Warning: no OIDC scopes specified, using default 'openid' scope only. This is a security risk for token reuse.")
181184
m.internalOidcScopes = []string{"openid"}
182185
}
186+
if m.OidcExtensions != "" {
187+
err = json.Unmarshal([]byte(m.OidcExtensions), &m.internalOidcExtensions)
188+
if err != nil || len(m.internalOidcExtensions) < 1 {
189+
return nil, errors.New("kafka error: improper OIDC Extensions format for authType 'oidc'")
190+
}
191+
}
183192
k.logger.Debug("Configuring SASL token authentication via OIDC.")
184193
case mtlsAuthType:
185194
if m.TLSClientCert != "" {

internal/component/kafka/sasl_oauthbearer.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,15 @@ type OAuthTokenSource struct {
3939
skipCaVerify bool
4040
}
4141

42-
func newOAuthTokenSource(oidcTokenEndpoint, oidcClientID, oidcClientSecret string, oidcScopes []string) OAuthTokenSource {
43-
return OAuthTokenSource{TokenEndpoint: oauth2.Endpoint{TokenURL: oidcTokenEndpoint}, ClientID: oidcClientID, ClientSecret: oidcClientSecret, Scopes: oidcScopes}
42+
func (m KafkaMetadata) getOAuthTokenSource() *OAuthTokenSource {
43+
return &OAuthTokenSource{
44+
TokenEndpoint: oauth2.Endpoint{TokenURL: m.OidcTokenEndpoint},
45+
ClientID: m.OidcClientID,
46+
ClientSecret: m.OidcClientSecret,
47+
Scopes: m.internalOidcScopes,
48+
Extensions: m.internalOidcExtensions,
49+
skipCaVerify: m.TLSSkipVerify,
50+
}
4451
}
4552

4653
var tokenRequestTimeout, _ = time.ParseDuration("30s")

pubsub/kafka/metadata.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ authenticationProfiles:
4848
Although not required, this field is recommended.
4949
example: '"openid,kafka-prod"'
5050
default: '"openid"'
51+
- name: oidcExtensions
52+
description: |
53+
String containing a JSON-encoded dictionary of OAuth2/OIDC extensions to request with the access token.
54+
example: |
55+
{"cluster":"kafka","poolid":"kafkapool"}
56+
type: string
5157
- title: "SASL Authentication"
5258
description: |
5359
Authenticate using SASL.

0 commit comments

Comments
 (0)