简体   繁体   English

AWS SES:用户无权对资源执行 ses:SendEmail

[英]AWS SES: User is not authorized to perform ses:SendEmail on resource

I have the following Python/boto3 script, taken directly from the AWS documentation :我有以下 Python/boto3 脚本,直接取自AWS 文档

import boto3
from botocore.exceptions import ClientError

# Replace sender@example.com with your "From" address.
# This address must be verified with Amazon SES.
SENDER = "mailman@sender.com"

# Replace recipient@example.com with a "To" address. If your account 
# is still in the sandbox, this address must be verified.
RECIPIENT = "joe@receiver.com"

# If necessary, replace us-west-2 with the AWS Region you're using for Amazon SES.
AWS_REGION = "eu-central-1"

# The subject line for the email.
SUBJECT = "Amazon SES Test (SDK for Python)"

# The email body for recipients with non-HTML email clients.
BODY_TEXT = ("Amazon SES Test (Python)\r\n"
             "This email was sent with Amazon SES using the "
             "AWS SDK for Python (Boto).")

# The HTML body of the email.
BODY_HTML = """<html>
<head></head>
<body>
  <h1>Amazon SES Test (SDK for Python)</h1>
  <p>This email was sent with
    <a href='https://aws.amazon.com/ses/'>Amazon SES</a> using the
    <a href='https://aws.amazon.com/sdk-for-python/'>
      AWS SDK for Python (Boto)</a>.</p>
</body>
</html>
            """

# The character encoding for the email.
CHARSET = "UTF-8"

# Create a new SES resource and specify a region.
client = boto3.client(
    'ses', aws_access_key_id='AKIA[REDACTED]', aws_secret_access_key='[REDACTED]',
    region_name=AWS_REGION
)

# Try to send the email.
try:
    # Provide the contents of the email.
    response = client.send_email(
        Destination={
            'ToAddresses': [
                RECIPIENT,
            ],
        },
        Message={
            'Body': {
                'Html': {
                    'Charset': CHARSET,
                    'Data': BODY_HTML,
                },
                'Text': {
                    'Charset': CHARSET,
                    'Data': BODY_TEXT,
                },
            },
            'Subject': {
                'Charset': CHARSET,
                'Data': SUBJECT,
            },
        },
        Source=SENDER,
    )
# Display an error if something goes wrong. 
except ClientError as e:
    print(e.response['Error']['Message'])
else:
    print("Email sent! Message ID:"),
    print(response['MessageId'])

Both domains (sender.com and receiver.com) are verified in SES;两个域(sender.com 和 receiver.com)都在 SES 中进行了验证; SES is still in sandbox mode. SES 仍处于沙盒模式。 The AWS credentials I am using are for a user with the following policy attached (via its group):我使用的 AWS 凭证适用于附加了以下策略的用户(通过其组):

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "*",
            "Resource": "*"
        }
    ]
}

When I'm running the script I get the following error:当我运行脚本时,出现以下错误:

User `arn:aws:iam::[REDACTED]:user/[REDACTED]' is not authorized to perform `ses:SendEmail' on resource `arn:aws:ses:eu-central-1:[REDACTED]:identity/receiver.com'.

When using "Send test email" from the AWS console with the same parameters everything works as expected.当使用相同参数从 AWS 控制台使用“发送测试电子邮件”时,一切都按预期工作。

What's the issue here?这里有什么问题?

The issue in my case was generated by an "enforce multi-factor authentication" policy, similar to the one in the docs ;我的问题是由“强制多因素身份验证”政策产生的,类似于文档中的政策 this policy enforces MFA for both the console and API (ie, when using long-lived credentials) and denies any action missing it:此策略对控制台和 API 强制执行 MFA(即,当使用长期凭据时)并拒绝任何缺少它的操作:

{
    "Sid": "DenyAllExceptListedIfNoMFA",
    "Effect": "Deny",
    "NotAction": [
        "iam:CreateVirtualMFADevice",
        "iam:EnableMFADevice",
        "iam:GetUser",
        "iam:ListMFADevices",
        "iam:ListVirtualMFADevices",
        "iam:ResyncMFADevice",
        "sts:GetSessionToken"
    ],
    "Resource": "*",
    "Condition": {
       "BoolIfExists": {
           "aws:MultiFactorAuthPresent": "false"
       }
    }
}

To fix this BoolIfExists can be changed to Bool , but also see this answer .要修复此BoolIfExists可以更改为Bool ,但也请参阅此答案

And always check all your IAM Policies!并始终检查您的所有IAM 政策!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM