我如何使用静态凭据(访问密钥和秘密访问密钥)使用 swift 从 iOS 应用程序将文件上传到 s3 存储桶。我已经尝试了放大指南,但我无法生成 json 文件,当我尝试配置它时出现此错误
UnrecognizedClientException:请求中包含的安全令牌无效。
但是我可以使用 bash 脚本(curl)上传文件,当我尝试复制相同的文件时,我看到以下错误,我现在可以使用下面的方法而不是使用 AWS 放大库来实现,无论哪个有效第一的
我们计算的请求签名与您提供的签名不匹配。检查您的 AWS 秘密访问密钥和签名方法。有关详细信息,请参阅 REST 身份验证和 SOAP 身份验证了解详细信息。
下面是工作 bash 脚本,
file_to_upload=card.jpg
bucket=dash-poc
filepath="/${bucket}/${file_to_upload}"
contentType="image/jpeg"
dateValue=`date -R`
signature_string="PUT\n\n${contentType}\n${dateValue}\n${filepath}"
signature_hash=`echo -en ${signature_string} | openssl sha1 -hmac ${s3_secret_key} -binary | base64`
# actual curl command to do PUT operation on s3
echo $signature_hash
curl -v -X PUT -T "${file_to_upload}" \
-H "Host: *********.com" \
-H "Date: ${dateValue}" \
-H "Content-Type: ${contentType}" \
-H "Authorization: AWS ${s3_access_key}:${signature_hash}" \
https://**********.com/dash-poc/card.jpg
编辑:用于 v4 签名
func signS3RequestV4(urlRequest : NSMutableURLRequest, credentials: AWSCredentials) -> String{
let awsEndpoint = AWSEndpoint(region: .EUWest2, serviceName: "s3", url: URL(string: "******.com/")!)
urlRequest.setValue(awsEndpoint!.hostName, forHTTPHeaderField: "host")
let date = Date()
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = AWSDateISO8601DateFormat2
dateFormatter.timeZone = TimeZone(identifier: "UTC")
let dateStamp = dateFormatter.string(from: date)
urlRequest.setValue(dateStamp, forHTTPHeaderField: "x-amz-date")
let dateFormatterShort = DateFormatter()
dateFormatterShort.dateFormat = AWSDateShortDateFormat1
let dateStampShort = dateFormatterShort.string(from: date)
let scope = String(format: "%@/%@/%@/%@", dateStampShort, awsEndpoint!.regionName, (awsEndpoint?.serviceName)!, AWSSignatureV4Terminator)
let signingCredentials = String(format: "%@/%@", credentials.accessKey, scope)
let httpMethod = urlRequest.httpMethod
let path = urlRequest.url!.path
let query = urlRequest.url?.query ?? ""
let contentSha256 = AWSSignatureSignerUtility.hexEncode(String(data: AWSSignatureSignerUtility.hash(urlRequest.httpBody), encoding: String.Encoding.ascii))
urlRequest.setValue(contentSha256, forHTTPHeaderField: "x-amz-content-sha256")
let headers = urlRequest.allHTTPHeaderFields
let canonicalRequest = AWSSignatureV4Signer.getCanonicalizedRequest(httpMethod, path: path, query: query, headers: headers, contentSha256: contentSha256)
let stringToSign = String(format: "%@\n%@\n%@\n%@",
AWSSignatureV4Algorithm,
urlRequest.value(forHTTPHeaderField: "x-amz-date")!,
scope, AWSSignatureSignerUtility.hexEncode(AWSSignatureSignerUtility.hashString(canonicalRequest)))
print("AWS4 String to Sign \(stringToSign)")
let kSigning = AWSSignatureV4Signer.getV4DerivedKey(credentials.secretKey, date: dateStampShort, region: awsEndpoint?.regionName, service: awsEndpoint?.serviceName)
let signature = AWSSignatureSignerUtility.sha256HMac(with: stringToSign.data(using: String.Encoding.utf8), withKey: kSigning)
let signatureString = AWSSignatureSignerUtility.hexEncode(String(data: signature, encoding: String.Encoding.ascii))
let authorization = String(format: "%@ Credential=%@, SignedHeaders=%@, Signature=%@",
AWSSignatureV4Algorithm,
signingCredentials,
AWSSignatureV4Signer.getSignedHeadersString(headers), signatureString)
return authorization
}
请指导我完成此操作,任何帮助将不胜感激。