I have an S3 bucket hosting objects which my users can download through my application. I am using Cloudfront for CDN with signed URLs. Everything works as expected in the US, but when my users in another country(India) try to download the same objects they get an error saying The remote server returned an error : (403) Forbidden
I verified that I have not put any geo restrictions in the CloudFront distributions
My Origin Name and Domain Path configured in CloudFront is in the format xyz-final-bucket.s3.us-west-2.amazonaws.com
Below is the code which generates the Signed-URLs for CloudFront :
Public Shared Function CreateCannedSignedURL(ByVal urlString As String, ByVal durationUnits As String, ByVal durationNumber As String, ByVal CannedPolicy As String, ByVal privateKey As String, ByVal privateKeyId As String) As String
Dim timeSpanInterval As TimeSpan = GetDuration(durationUnits, durationNumber)
Dim strPolicy As String = CreatePolicyStatement(CannedPolicy, urlString, DateTime.Now, DateTime.Now.Add(timeSpanInterval), "0.0.0.0/0")
If "Error!" = strPolicy Then Return "Invalid time frame. Start time cannot be greater than end time."
Dim strExpiration As String = CopyExpirationTimeFromPolicy(strPolicy)
Dim bufferPolicy As Byte() = Encoding.ASCII.GetBytes(strPolicy)
Using cryptoSHA1 As SHA1CryptoServiceProvider = New SHA1CryptoServiceProvider()
bufferPolicy = cryptoSHA1.ComputeHash(bufferPolicy)
Dim providerRSA As RSACryptoServiceProvider = New RSACryptoServiceProvider()
Dim xmlPrivateKey As XmlDocument = New XmlDocument()
Dim pemText As String
pemText = privateKey
Dim xmlContent = RsaKeyConverterHelper.PemToXml(pemText)
xmlPrivateKey.LoadXml(xmlContent)
providerRSA.FromXmlString(xmlPrivateKey.InnerXml)
Dim rsaFormatter As RSAPKCS1SignatureFormatter = New RSAPKCS1SignatureFormatter(providerRSA)
rsaFormatter.SetHashAlgorithm("SHA1")
Dim signedPolicyHash As Byte() = rsaFormatter.CreateSignature(bufferPolicy)
Dim strSignedPolicy As String = ToUrlSafeBase64String(signedPolicyHash)
Dim downloadLink As String = urlString & "?Expires=" & strExpiration & "&Signature=" & strSignedPolicy & "&Key-Pair-Id=" & privateKeyId
Return downloadLink
End Using
End Function
All the objects in my bucket are stored with One-Zone IA. I am not sure if this is the reason because I have tried changing it standard as well.
Are any changes required in my configuration to enable downloads from all geo-locations?
The issue was with the machine that was initiating the request in India. It's time was not synced with its timezone. The time set on that client was around an hour behind the actual time. So when an expiration timestamp got generated it was always behind the actual time. After fixing the time on the client the issue got resolved.