Мне не удается добиться успешной проверки подписи, когда я отправляю тестовое сообщение по адресу жалоба@simulator.amazonses.com. Ниже приведен мой текущий соответствующий код Python после некоторых проб и ошибок. Но я всегда получаю ошибку InvalidSignature. Есть идеи, что я делаю не так?
def create_string_to_sign(payload):
print(payload)
string_to_sign = (
f"""Message:\n{payload['Message']}\nMessageId:\n{payload['MessageId']}\n"""
)
# 'Subject' is optional, add it only if present in the payload
if "Subject" in payload:
string_to_sign += f"Subject:\n{payload['Subject']}\n"
string_to_sign += f"""Timestamp:\n{payload['Timestamp']}\nTopicArn:\n{payload['TopicArn']}\nType:\n{payload['Type']}\n"""
# Add 'UnsubscribeURL' only if present
if "UnsubscribeURL" in payload:
string_to_sign += f"UnsubscribeURL:\n{payload['UnsubscribeURL']}\n"
print(string_to_sign)
return string_to_sign
class AmazonSNSSESWebhookView(WebhookView):
"""
Validate and process webhook events from Amazon SNS for Amazon SES spam complaints.
"""
def validate(self):
"""
Sample payload from Amazon SNS
{
"Type" : "Notification",
"MessageId" : "1c2a7465-1f6b-43a2-b92f-0f24b9c7f3c5",
"TopicArn" : "arn:aws:sns:us-east-1:123456789012:SES_SpamComplaints",
"Message" : "{\"notificationType\":\"Complaint\",\"complaint\":{\"complainedRecipients\":[{\"emailAddress\":\"example@example.com\"}],\"complaintFeedbackType\":\"abuse\",\"arrivalDate\":\"2024-09-25T14:00:00.000Z\"},\"mail\":{\"timestamp\":\"2024-09-25T13:59:48.000Z\",\"source\":\"sender@example.com\",\"messageId\":\"1234567890\"}}",
"Timestamp" : "2024-09-25T14:00:00.000Z",
"SignatureVersion" : "1",
"Signature" : "...",
"SigningCertURL" : "https://sns.us-east-1.amazonaws.com/Sim ... ervice.pem",
"UnsubscribeURL" : "https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe"
}
"""
payload = json.loads(self.request.body)
# Ensure that the sender is actually Amazon SNS
signing_cert_url = payload["SigningCertURL"]
if not signing_cert_url.startswith(
f"https://sns.{settings.AWS_SES_REGION_NAME}.amazonaws.com/"
):
return False
# We need to handle the subscription confirmation
if payload["Type"] == "SubscriptionConfirmation":
response = requests.get(payload["SubscribeURL"])
if response.status_code != 200:
logger.error(
f"Failed to confirm Amazon SNS subscription. Payload: {payload}"
)
return False
else:
return True
# Message Type: Ensure that you only process SNS messages of type Notification.
# There are other message types (e.g., SubscriptionConfirmation and UnsubscribeConfirmation),
# which you may want to handle separately. For SubscriptionConfirmation,
# you should respond to confirm the subscription.
if payload["Type"] != "Notification":
return False
# Check that the message is recent, protect against replay attacks
# Ignore if it is old
sns_datetime = parser.parse(payload["Timestamp"])
current_datetime = datetime.now(timezone.utc)
time_window = timedelta(minutes=5)
if sns_datetime < current_datetime - time_window:
return False
# Retrieve the certificate.
signing_cert = x509.load_pem_x509_certificate(
requests.get(signing_cert_url).content
)
decoded_signature = base64.b64decode(payload["Signature"])
signature_hash = (
hashes.SHA1() if payload["SignatureVersion"] == "1" else hashes.SHA256()
)
# Sign the string.
string_to_sign = create_string_to_sign(payload)
return signing_cert.public_key().verify(
decoded_signature,
string_to_sign.encode("UTF-8"),
padding=padding.PKCS1v15(),
algorithm=signature_hash,
)
Подробнее здесь: https://stackoverflow.com/questions/790 ... -in-python
Проверка подписей Amazon SNS в Python ⇐ Python
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение