0
votes

I want to use S3 for hosting files which I upload via a Kotlin Spring-Boot application. I followed the instructions and used various other documentations plus tried a few solutions for similar issues found on stackoverflow. I always receive a 403 error. How do I set up S3 and IAM so I can upload the file? And how do I find out what's wrong? Any help would be appreciated.

I have activated access logging, which takes ages and hasn't helped me much yet, especially because it takes like 45 minutes to generate the logs. Ignoring the responses with status 200, the following messages appear in the logs (bucket represents the name of my bucket):

  • GET /bucket?encryption= HTTP/1.1" 404 ServerSideEncryptionConfigurationNotFoundError
  • GET /bucket?cors= HTTP/1.1" 404 NoSuchCORSConfiguration
  • GET /bucket?policy= HTTP/1.1" 404 NoSuchBucketPolicy
  • PUT /bucket?policy= HTTP/1.1" 400 MalformedPolicy
  • GET /bucket/?policyStatus HTTP/1.1" 404 NoSuchBucketPolicy
  • PUT /bucket?policy= HTTP/1.1" 403 AccessDenied

I build an AmazonS3 instance by

AmazonS3ClientBuilder.defaultClient()

I've checked the implementation and it retrieves the credentials from the environment variables I've set up.

To submit the file, I use the following method in my S3Service implementation:

private fun uploadFileToBucket(fileName: String, file: File) {
    s3client.putObject(
            PutObjectRequest(bucketName, fileName, file)
                    .withCannedAcl(CannedAccessControlList.PublicRead)
    )
}

This is my policy for the IAM user (the user inherits the policy from a group):

{
"Version": "2012-10-17",
"Statement": [
    {
        "Sid": "VisualEditor0",
        "Effect": "Allow",
        "Action": [
            "s3:PutAccountPublicAccessBlock",
            "s3:GetAccountPublicAccessBlock",
            "s3:ListAllMyBuckets",
            "s3:HeadBucket"
        ],
        "Resource": "*"
    },
    {
        "Sid": "VisualEditor1",
        "Effect": "Allow",
        "Action": "s3:*",
        "Resource": [
            "arn:aws:s3:::bucket",
            "arn:aws:s3:::bucket/*"
        ]
    }
]

}

And this is the bucket policy:

{
    "Version": "2012-10-17",
    "Id": "PolicyId",
    "Statement": [
        {
            "Sid": "StmtId",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::account:user/username"
            },
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::bucket"
        }
    ]
}

In the end, I want to be able to put files onto the bucket and want to provide public access to those. For example I want to upload images from an Angular app, uploading them via my Spring Boot application and display them on the Angular app. Right now I can't even upload them via Postman without a 403 error.

2

2 Answers

1
votes

The IAM policy could be shortened to this:

{
 "Version": "2012-10-17",
 "Statement": [
    {
        "Sid": "VisualEditor1",
        "Effect": "Allow",
        "Action": "s3:*",
        "Resource": [
            "arn:aws:s3:::bucket",
            "arn:aws:s3:::bucket/*"
        ]
    }
 ]
}

In other words, that second statement gives full S3 access, so the first statement in your IAM policy is pointless.

Your bucket policy probably has something wrong with it. It's hard to tell because you've replaced several values with placeholders I think. However, you don't need a bucket policy at all in this instance. I would just delete it.

0
votes

As Mark B pointed out, the IAM policy can be shortened and the bucket policy isn't of any need anyway. However, uploading a file worked with those settings and with the modified one. The problem in my code and with the S3 configuration was that I tried to modify the ACL without allowing that in my bucket. As I marked in the screenshot below, blocking new public ACLs must be disabled, otherwise the server respond with a 403 by definition.

Setting up public access