Amazon S3 C# SDK “The underlying connection was cl

2019-09-16 04:14发布

问题:

I am using Amazon C# SDK Version 1.5.36.0. I created a class to upload files to the Amazon S3 and in My machine it works just great, no error at all, but when I run it in the production server I get the following error: "The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel."

I´m pasting bellow the piece of code to which I refer to:

public bool SaveFile(S3Folder folder, string customFolder, string fileName, Stream stream, bool publicFile)
    {
        // Validações
        if (string.IsNullOrEmpty(fileName) || stream == null)
            return false;

        using (var s3Client = new AmazonS3Client(accessKey, secretKey, region))
        {
            var request = new PutObjectRequest();
            request.BucketName = bucketName;
            request.InputStream = stream;

            if (!string.IsNullOrEmpty(customFolder))
                request.Key = GetFolder(folder) + "/" + customFolder + "/" + fileName;
            else
                request.Key = GetFolder(folder) + "/" + fileName;

            if (!publicFile)
                request.CannedACL = S3CannedACL.Private;
            else
                request.CannedACL = S3CannedACL.PublicRead;

            s3Client.PutObject(request);

            return true;
        }
    }

It is a method in my class to save the file. S3Folder is an enum and GetFolder just return a string with the folder name.

Can you guys help me please? I have been looking for it but no answer solved my problem yet.

Thanks in advance.

回答1:

I have solved it. I set it to http when creating the client. See the code bellow:

public bool SaveFile(S3Folder folder, string customFolder, string fileName, Stream stream, bool publicFile)
    {
        // Validações
        if (string.IsNullOrEmpty(fileName) || stream == null)
            return false;

        AmazonS3Config S3Config = new AmazonS3Config()
        {
            ServiceURL = "s3.amazonaws.com",
            CommunicationProtocol = Protocol.HTTP,
            RegionEndpoint = region
        };

        using (var s3Client = new AmazonS3Client(accessKey, secretKey, S3Config))
        {

            var request = new PutObjectRequest();
            request.BucketName = bucketName;
            request.InputStream = stream;

            if (!string.IsNullOrEmpty(customFolder))
                request.Key = GetFolder(folder) + "/" + customFolder + "/" + fileName;
            else
                request.Key = GetFolder(folder) + "/" + fileName;

            if (!publicFile)
                request.CannedACL = S3CannedACL.Private;
            else
                request.CannedACL = S3CannedACL.PublicRead;

            s3Client.PutObject(request);

            return true;
        }
    }


回答2:

Instead of setting the CommunicationProtocol to HTTP, which compromises security, you can stick to HTTPS if instead you set ForcePathStyle = true in your S3Config. (This requires at least version 2.0.13.0 of AWSSDK.dll.)

The reason this is needed is explained well here: http://shlomoswidler.com/2009/08/amazon-s3-gotcha-using-virtual-host.html. Briefly, S3 supports two versions of the path to your object, one like

https://s3.amazonaws.com/mybucket.mydomain.com/myObjectKey

and one like

https://mybucket.mydomain.com.s3.amazonaws.com/myObjectKey

The second form, which is used by default, causes problems with the security certificate; ForcePathStyle causes the S3Client to use the first form.