2011-05-10 7 views
11

저는 Amazon S3 환경을 사용하여 C# Webapplication 용 이미지를 저장하고 있습니다. 내가 한 양동이의 개체에 만료 URL을 만들 수 있다는 사실을 알고 Amazon S3 - 버킷의 객체를 가리키는 URL을 올바르게 작성하는 방법?

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

처럼 내가 배운 S3 documentation에서 기본 URL에 액세스하는 것을 객체 보인다. 두 가지 질문 :

  1. 일반적으로 만료되는 URL을 사용해야합니까?
  2. 어떻게 만료 URL을 만들 수 있습니까?
+0

감사합니다! 내게는 질문이 어떤 대답보다 더 유용 할 때다. :) –

답변

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

+0

@Lee Gunn 만료 시간없이 URL이 필요합니다. 그렇게 할 방법이 있습니까? –

+0

@ArturKeyan - 작동하지 않으면 시도해보십시오 만료 기한을 오래 사용할 수 있다고 가정합니다. –

2

이 S3SignURL의 코드이며, 그것은 어떤 외부 DLL이 버전 3 (S3) SDK와 함께 순수한 핵심 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

없습니다 사용, 아마존은하지에 충분한 API를 변경 이건의 대답과 양립 할 수 있어야한다. 여기 문서 : 기본 URL에 대한이 질문과 정보를

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); 
}