简体   繁体   中英

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 :

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; SES is still in sandbox mode. The AWS credentials I am using are for a user with the following policy attached (via its group):

{
    "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.

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:

{
    "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 .

And always check all your IAM Policies!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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