Я пытаюсь реализовать Cognito MFA с помощью электронной почты. Следуя документации здесь: https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-custom-sms-sender.html
Я использую лямбда-выражение Python, которое запускается Cognito, когда пользователь вводит свой пароль пользователя+. Однако я получаю следующую ошибку с библиотекой aws-encryption-sdk-python:
Traceback (most recent call last):
File "/var/task/aws_encryption_sdk/internal/formatting/deserialize.py", line 87, in _verified_version_from_id
return SerializationVersion(version_id)
File "/var/lang/lib/python3.9/enum.py", line 384, in __call__
return cls.__new__(cls, value)
File "/var/lang/lib/python3.9/enum.py", line 702, in __new__
raise ve_exc
ValueError: 65 is not a valid SerializationVersion
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/var/task/aws_encryption_sdk/__init__.py", line 186, in decrypt
plaintext = decryptor.read()
File "/var/task/aws_encryption_sdk/streaming_client.py", line 250, in read
self._prep_message()
File "/var/task/aws_encryption_sdk/streaming_client.py", line 782, in _prep_message
self._header, self.header_auth = self._read_header()
File "/var/task/aws_encryption_sdk/streaming_client.py", line 797, in _read_header
header, raw_header = deserialize_header(self.source_stream, self.config.max_encrypted_data_keys)
File "/var/task/aws_encryption_sdk/internal/formatting/deserialize.py", line 336, in deserialize_header
version = _verified_version_from_id(version_id)
File "/var/task/aws_encryption_sdk/internal/formatting/deserialize.py", line 89, in _verified_version_from_id
raise NotSupportedError("Unsupported version
{}
".format(version_id), error)
aws_encryption_sdk.exceptions.NotSupportedError: ('Unsupported version 65', ValueError('65 is not a valid SerializationVersion'))
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/var/task/aws_encryption_sdk/streaming_client.py", line 218, in __exit__
self.close()
File "/var/task/aws_encryption_sdk/streaming_client.py", line 985, in close
raise SerializationError("Footer not read")
aws_encryption_sdk.exceptions.SerializationError: Footer not read
Никакую 65 версию я никуда не устанавливаю. Это мой код, и я уже проверил, что переменные env передаются правильно:
import os
import json
import boto3
from botocore.exceptions import ClientError
from common.utils import *
from common.sqlUtils import *
from common.authentication import *
from common.authorization import *
from common.exceptions import GeneralException
from sendgrid import SendGridAPIClient
from sendgrid.helpers.mail import Mail
import aws_encryption_sdk
from aws_encryption_sdk.identifiers import CommitmentPolicy
# Configure the encryption SDK client with the KMS key from the environment variables.
awsEncryptionSdkClient = aws_encryption_sdk.EncryptionSDKClient(
commitment_policy=CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT
)
decryptionKeyArn = os.environ["cognitoCodeEncryptionKeyArn"]
kms_key_provider = aws_encryption_sdk.StrictAwsKmsMasterKeyProvider(
key_ids=[decryptionKeyArn]
)
def sendEmail(event, context):
try:
#TODO check if email is verified, user is confirmed, etc
plaintextCode = None
if "request" in event and "code" in event["request"]:
print("Line 35: ", event)
encryptedCode = event["request"]["code"]
print("encryptedCode: ", encryptedCode)
print("decryptionKeyArn ", decryptionKeyArn)
plaintextCode, plaintextHeader = awsEncryptionSdkClient.decrypt(
source=encryptedCode,
key_provider=kms_key_provider
)
print("plaintextCode:", plaintextCode)
subject = None
html_content = None
if plaintextCode is not None:
subject = 'Code'
html_content = f'<strong>Your code is: {plaintextCode}</strong>'
message = Mail(
from_email='[email protected]',
to_emails=event["request"]["userAttributes"]["email"],
subject=subject,
html_content=html_content
)
sendgridSecret = getSecret(os.environ['cognitoSendgridSecretArn'])
if isJson(sendgridSecret):
sendgridSecret = json.loads(sendgridSecret)['SENDGRID_API_KEY']
sg = SendGridAPIClient(sendgridSecret)
response = sg.send(message)
print(response.status_code)
print(response.body)
print(response.headers)
#TODO check if email was sent successfully
return json_response({"sendgrid message": response})
except Exception as e:
httpCode = 500
if isinstance(e, GeneralException):
httpCode = e.httpCode
print(str(e))
return json_response({"message": str(e)}, httpCode)
Любые указатели будут оценены!
Когда лямбда-функции передается зашифрованный текстовый код, он закодирован в формате Base64. При передаче сюда зашифрованного кода его необходимо декодировать в формате Base64 и преобразовать в двоичный код.
import base64
...
plaintextCode, plaintextHeader = awsEncryptionSdkClient.decrypt(
source=base64.b64decode(encryptedCode),
key_provider=kms_key_provider
)
Это работает! Большое спасибо, Кенни
Я также опубликовал проблему с библиотекой для справки: github.com/aws/aws-encryption-sdk-python/issues/695