2011-05-10 184 views
11

我正在使用Amazon S3环境为C#Web应用程序存储图像。从S3 documentation我了解到,那基本URL访问对象看起来像Amazon S3 - 如何正确构建指向存储桶中对象的URL?

http://[bucket-name].S3.amazonaws.com/[key]

我知道,一个可以建立过期的网址在桶中的对象。两个问题:

  1. 应该通常使用到期URL吗?
  2. 我该如何建立一个到期的url?
+0

谢谢你这个问题和信息有关的基本网址!对于我来说这是一个案例,当问题比任何答案更有用:) – 2017-05-19 14:22:56

回答

23

如果您想限制访问权限,则只需构建即将到期的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); 
} 
+0

一切都回答了。非常感谢你。 – Mats 2011-05-10 12:06:49

+0

@李Gunn我需要一个URL没有到期时间,有没有办法做到这一点? – 2014-05-07 12:54:45

+0

@ArturKeyan - 尝试没有它,如果它不起作用我想你可以使用一个大的到期日期。 – 2014-05-08 07:40:58

2

这是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)); 
     } 
    } 
} 
0

随着第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); 
} 
相关问题