我正在使用Amazon S3环境为C#Web应用程序存储图像。从S3 documentation我了解到,那基本URL访问对象看起来像Amazon S3 - 如何正确构建指向存储桶中对象的URL?
http://[bucket-name].S3.amazonaws.com/[key]
我知道,一个可以建立过期的网址在桶中的对象。两个问题:
- 应该通常使用到期URL吗?
- 我该如何建立一个到期的url?
我正在使用Amazon S3环境为C#Web应用程序存储图像。从S3 documentation我了解到,那基本URL访问对象看起来像Amazon S3 - 如何正确构建指向存储桶中对象的URL?
http://[bucket-name].S3.amazonaws.com/[key]
我知道,一个可以建立过期的网址在桶中的对象。两个问题:
如果您想限制访问权限,则只需构建即将到期的URL。
下面是一些代码,用于生成在3分钟内到期的签名url。
using (var s3Client = AWSClientFactory.CreateAmazonS3Client("MyAccessKey", "MySecretKey"))
{
GetPreSignedUrlRequest request = new GetPreSignedUrlRequest()
.WithBucketName("MyBucketName")
.WithKey("MyFileKey")
.WithProtocol(Protocol.HTTP)
.WithExpires(DateTime.Now.AddMinutes(3));
string url = s3Client.GetPreSignedURL(request);
}
一切都回答了。非常感谢你。 – Mats 2011-05-10 12:06:49
@李Gunn我需要一个URL没有到期时间,有没有办法做到这一点? – 2014-05-07 12:54:45
@ArturKeyan - 尝试没有它,如果它不起作用我想你可以使用一个大的到期日期。 – 2014-05-08 07:40:58
这是S3SignURL代码,它不使用外DLL只是纯粹的核心C#
https://github.com/DigitalBodyGuard/S3SignURL/
using System;
using System.Collections.Generic;
using System.Text;
namespace s3_polocySigning
{
public static class Encode
{
// static string thanks = "http://stackoverflow.com/questions/6999648/signing-post-form-in-c-sharp-for-uploading-to-amazon-s3";
public static string BuildURL(string AccessKey, string SecretKey, DateTime timeToExpire, string BucketName, string FileKey)
{
System.Security.Cryptography.HMAC hmacProvider = System.Security.Cryptography.HMAC.Create();
string returnString = string.Empty;
hmacProvider.Key = System.Text.ASCIIEncoding.ASCII.GetBytes(SecretKey);
string expirationString = ConvertToUnixTimestamp(timeToExpire).ToString();
//System.Uri.UriSchemeHttp &/ System.Web.HttpUtility.UrlEncode
string assembledRequest = "GET" + "\n" + "\n" + "\n" + expirationString + "\n" + "/" + BucketName + "/" + UrlEncode(FileKey);
byte[] hashedSignature = hmacProvider.ComputeHash(System.Text.ASCIIEncoding.ASCII.GetBytes(assembledRequest));
returnString = Convert.ToBase64String(hashedSignature);
return "https://" + "s3.amazonaws.com/" + BucketName + "/" + FileKey + "?AWSAccessKeyId=" + AccessKey + "&Expires=" + expirationString + "&Signature=" + UrlEncode(returnString);
}
private static double ConvertToUnixTimestamp(DateTime ExpDate)
{
if (DateTime.MinValue == ExpDate)
return 2133721337;
DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0);
TimeSpan diff = ExpDate - origin;
return Convert.ToDouble(Math.Floor(diff.TotalSeconds));
}
public static string GetSig(string policyStr, string secretKey)
{
policyStr = GetBase64_string(policyStr);
var signature = new System.Security.Cryptography.HMACSHA1(GetBase64(secretKey));
var bytes = GetBase64(policyStr);
var moreBytes = signature.ComputeHash(bytes);
var encodedCanonical = Convert.ToBase64String(moreBytes);
return encodedCanonical;
}
public static string GetBase64_string(string policyStr)
{
policyStr = policyStr.Replace("/r", "").Replace("/n", "").Replace(System.Environment.NewLine, "\n");
return Convert.ToBase64String(Encoding.ASCII.GetBytes(policyStr));
}
public static byte[] GetBase64(string policyStr)
{
return Encoding.ASCII.GetBytes(policyStr);
}
// ThanksTo = "http://www.west-wind.com/weblog/posts/2009/Feb/05/Html-and-Uri-String-Encoding-without-SystemWeb";
// avoid useing System.Web.HttpUtility.UrlEncode
/// <summary>
/// UrlEncodes a string without the requirement for System.Web
/// </summary>
/// <param name="String"></param>
/// <returns></returns>
// [Obsolete("Use System.Uri.EscapeDataString instead")]
public static string UrlEncode(string text)
{
// Sytem.Uri provides reliable parsing
return System.Uri.EscapeDataString(text);
}
/// <summary>
/// UrlDecodes a string without requiring System.Web
/// </summary>
/// <param name="text">String to decode.</param>
/// <returns>decoded string</returns>
public static string UrlDecode(string text)
{
// pre-process for + sign space formatting since System.Uri doesn't handle it
// plus literals are encoded as %2b normally so this should be safe
text = text.Replace("+", " ");
return System.Uri.UnescapeDataString(text);
}
/// <summary>
/// Retrieves a value by key from a UrlEncoded string.
/// </summary>
/// <param name="urlEncoded">UrlEncoded String</param>
/// <param name="key">Key to retrieve value for</param>
/// <returns>returns the value or "" if the key is not found or the value is blank</returns>
public static string GetUrlEncodedKey(string urlEncoded, string key)
{
urlEncoded = "&" + urlEncoded + "&";
int Index = urlEncoded.IndexOf("&" + key + "=", StringComparison.OrdinalIgnoreCase);
if (Index < 0)
return "";
int lnStart = Index + 2 + key.Length;
int Index2 = urlEncoded.IndexOf("&", lnStart);
if (Index2 < 0)
return "";
return UrlDecode(urlEncoded.Substring(lnStart, Index2 - lnStart));
}
}
}
随着第3版S3 SDK,亚马逊已经改变了API刚好够不与Lee Gunn的答案相容。文档浏览:
http://docs.aws.amazon.com/AmazonS3/latest/dev/ShareObjectPreSignedURLDotNetSDK.html
using (var s3Client = new AmazonS3Client(Amazon.RegionEndpoint.USEast1))
{
GetPreSignedUrlRequest request1 = new GetPreSignedUrlRequest
{
BucketName = "MyBucket",
Key = "MyKey",
Expires = DateTime.Now.AddMinutes(5)
};
string urlString = s3Client.GetPreSignedURL(request1);
}
谢谢你这个问题和信息有关的基本网址!对于我来说这是一个案例,当问题比任何答案更有用:) – 2017-05-19 14:22:56