Skip to content

Commit 9f7384c

Browse files
authored
Fix decoding bug in AWS_MSK_IAM mechanism (#2639)
1 parent e6abbbf commit 9f7384c

File tree

2 files changed

+29
-4
lines changed

2 files changed

+29
-4
lines changed

kafka/sasl/msk.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import hashlib
55
import hmac
66
import json
7+
import logging
78
import string
89

910
# needed for AWS_MSK_IAM authentication:
@@ -13,10 +14,14 @@
1314
# no botocore available, will disable AWS_MSK_IAM mechanism
1415
BotoSession = None
1516

17+
from kafka.errors import KafkaConfigurationError
1618
from kafka.sasl.abc import SaslMechanism
1719
from kafka.vendor.six.moves import urllib
1820

1921

22+
log = logging.getLogger(__name__)
23+
24+
2025
class SaslMechanismAwsMskIam(SaslMechanism):
2126
def __init__(self, **config):
2227
assert BotoSession is not None, 'AWS_MSK_IAM requires the "botocore" package'
@@ -27,22 +32,28 @@ def __init__(self, **config):
2732
self._is_done = False
2833
self._is_authenticated = False
2934

30-
def auth_bytes(self):
35+
def _build_client(self):
3136
session = BotoSession()
3237
credentials = session.get_credentials().get_frozen_credentials()
33-
client = AwsMskIamClient(
38+
if not session.get_config_variable('region'):
39+
raise KafkaConfigurationError('Unable to determine region for AWS MSK cluster. Is AWS_DEFAULT_REGION set?')
40+
return AwsMskIamClient(
3441
host=self.host,
3542
access_key=credentials.access_key,
3643
secret_key=credentials.secret_key,
3744
region=session.get_config_variable('region'),
3845
token=credentials.token,
3946
)
47+
48+
def auth_bytes(self):
49+
client = self._build_client()
50+
log.debug("Generating auth token for MSK scope: %s", client._scope)
4051
return client.first_message()
4152

4253
def receive(self, auth_bytes):
4354
self._is_done = True
4455
self._is_authenticated = auth_bytes != b''
45-
self._auth = auth_bytes.deode('utf-8')
56+
self._auth = auth_bytes.decode('utf-8')
4657

4758
def is_done(self):
4859
return self._is_done

test/sasl/test_msk.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import json
33
import sys
44

5-
from kafka.sasl.msk import AwsMskIamClient
5+
from kafka.sasl.msk import AwsMskIamClient, SaslMechanismAwsMskIam
66

77
try:
88
from unittest import mock
@@ -69,3 +69,17 @@ def test_aws_msk_iam_client_temporary_credentials():
6969
'x-amz-security-token': 'XXXXX',
7070
}
7171
assert actual == expected
72+
73+
74+
def test_aws_msk_iam_sasl_mechanism():
75+
with mock.patch('kafka.sasl.msk.BotoSession'):
76+
sasl = SaslMechanismAwsMskIam(security_protocol='SASL_SSL', host='localhost')
77+
with mock.patch.object(sasl, '_build_client', return_value=client_factory(token=None)):
78+
assert sasl.auth_bytes() != b''
79+
assert not sasl.is_done()
80+
assert not sasl.is_authenticated()
81+
sasl.receive(b'foo')
82+
assert sasl._auth == 'foo'
83+
assert sasl.is_done()
84+
assert sasl.is_authenticated()
85+
assert sasl.auth_details()

0 commit comments

Comments
 (0)