我们开发了一个利用Amazon AWS S3 SDK客户端从AWS桶获取对象(文件)的应用程序。该平台将要求系统能够访问s3.amazonaws.com。但是,我们的一些客户不想打开防火墙到amazon.com(当进入s3.amazonaws.com到网络浏览器时,它会重定向到aws.amazon.com/s3)。我们如何使用自己的域名站点重定向到Amazon AWS站点,并能够使用SDK for .NET获取对象(文件)?
谢谢, 宝林
答案 0 :(得分:0)
您可以使用CNAME来识别Host:
标头,但除非您设置了反向代理,否则您的客户端仍然必须允许其防火墙访问。见Customizing Amazon S3 URLs with CNAMEs
如果您希望所有客户端访问权限都通过您控制的IP地址,则可以使用反向代理。有很多关于为这个特定用例设置一个的教程:
您也可以在应用内代理请求。例如,使用MVC Core,Microsoft.AspNetCore.Proxy
middleware允许您设置传递给第三方的路由。
取自Joseph Woodward's网站的示例:
// Startup.cs
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
...
app.MapWhen(IsAdminPath, builder => builder.RunProxy(new ProxyOptions
{
Scheme = "http",
Host = "localhost",
Port = "8081"
}));
...
}
private static bool IsAdminPath(HttpContext httpContext)
{
return httpContext.Request.Path.Value.StartsWith(@"/admin/", StringComparison.OrdinalIgnoreCase);
}
要使用Windows服务创建代理,您可以使用WCF:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceContract(Namespace = ServiceNamespace)]
[DataContractFormat]
public class FileContentService : IFileContentService, INullContract
{
public FileContentService()
{
client = new AmazonS3Client(Amazon.RegionalEndpoint.USEast1);
}
[OperationContract, WebGet(UriTemplate = "Files/{fileId}")]
public io.Stream GetFileContent(string fileId)
{
GetObjectRequest request = new GetObjectRequest
{
BucketName = bucketName,
Key = fileId
};
var response = client.GetObject(request);
// copy relevant headers (MIME, ETag, Cache-Control, etc...)
// WebOperationContext.Current.OutgoingResponse.SetETag(etag);
// WebOperationContext.Current.OutgoingResponse.ContentType = foo;
// WebOperationContext.Current.OutgoingResponse.Headers
// .Add(HttpResponseHeader.CacheControl, "{cache options}");
return response.ResponseStream;
}
}
public class FileContentServiceManager : IDisposable
{
private ServiceHost shThis;
public FileContentServiceManager()
{
shThis = new ServiceHost(typeof(FileContentService), new Uri("https://localhost/foo/bar"));
shThis.AddServiceEndpoint(typeof(FileContentService), GetBinding(), "")
.Behaviors.Add(new WebHttpBehavior());
shThis.Open();
}
public void Dispose()
{
shThis.Close();
}
static Binding GetBinding()
{
var b = new WebHttpBinding();
b.MaxReceivedMessageSize = 28 * 1024 * 1024 * 2;
b.ReaderQuotas.MaxBytesPerRead = 4096 * 1024;
b.ReaderQuotas.MaxDepth = 32;
b.ReaderQuotas.MaxStringContentLength = 4096 * 1024;
b.ReaderQuotas.MaxArrayLength = 4096 * 1024;
b.Security.Mode = WebHttpSecurityMode.Transport;
CustomBinding result = new CustomBinding(b);
WebMessageEncodingBindingElement webMEBE = result.Elements.Find<WebMessageEncodingBindingElement>();
webMEBE.ContentTypeMapper = new MyMapper();
return result;
}
class MyMapper : WebContentTypeMapper
{
public override WebContentFormat GetMessageFormatForContentType(string contentType)
{
return WebContentFormat.Raw; // always
}
}
}
答案 1 :(得分:0)
最终我们使用了不同的方式来解决这个问题:我们在 URL 中添加了更具体的前缀以缩小对亚马逊网站的访问范围。 AWS 的命名约定要求前缀使用“-”而不是“.”。例如:我们需要使用“myproduct-bucket.s3.amazonaws.com”而不是“myproduct.bucket.s3.amamzonaws.com”。