访问Amazon S3

时间:2018-12-14 05:28:15

标签: amazon-web-services http amazon-s3 silverlight-5.0 http-status-code-407

我已经尝试了所有方法,但是我似乎无法解决仅在公司代理/防火墙后面的一个客户端发生的此问题。我们的Silverlight应用程序连接到Amazon S3,以下载/上传一些文档。仅在一个客户端和一个客户端上,它会返回407错误,然后应用程序将无法保存任何内容。

Inner Exception:
 System.ServiceModel.ProtocolException: [UnexpectedHttpResponseCode]
Arguments: 407,Proxy Authentication Required

我们在不同的客户处也遇到了类似的情况,但更多的是CORS问题。为了解决这个问题,我使用云前端来伪造一个子域,然后该子域访问S3存储桶并解决了该问题。我希望它也可以与此客户端一起修复它,但事实并非如此。

我尝试按照很多答案的建议将此代码添加到web.config中

 <system.net>
      <defaultProxy useDefaultCredentials="true" >
      </defaultProxy>
   </system.net>

我已经阅读了有关使用用户名和密码通过基本身份验证传递代理标头的文章,但是我不确定这将如何帮助我们。客户端使用代理服务器,并且它要求的任何身份验证都在我们的域之外。

**Additional Information**

Silverlight代码引用2个服务。一种是我们的wcf服务,它检索应用程序的所有数据。一种是使用Amazon Soap api的Amazon S3服务,其端点位于http://s3.amazonaws.com/doc/2006-03-01/AmazonS3.wsdl

如果我进入我们的应用程序并且仅使用不对Amazon S3 api进行任何调用的系统部分,则该应用程序可以正常运行。一旦我进入呼叫S3的系统部分,问题就开始了。有趣的是,对S3的调用很好,我可以检索到文档,但是对我们的wcf服务的任何调用都会返回407。

有什么想法吗?

**Update 2**

基于Elliot Nelson的评论,我检查了用于在应用程序中发出http请求的堆栈。事实证明,默认情况下,我们对HTTP和https请求都使用客户端http。这是App.xaml构造函数中的代码

  public App()
        {
            Startup += Application_Startup;
            UnhandledException += Application_UnhandledException;

            InitializeComponent();

            WebRequest.RegisterPrefix("http://", WebRequestCreator.ClientHttp);
            WebRequest.RegisterPrefix("https://", WebRequestCreator.ClientHttp);

        }

现在,了解clienthttp和browserhttp之间的区别以及何时使用它们。另外,切换到浏览器http的潜在影响/问题。

**Update 3**

是否有一种方法可以请求浏览器以信任模式运行浏览器中的Silverlight应用程序,这是否可以绕过此问题?

3 个答案:

答案 0 :(得分:2)

(答案2)

因此,很可能(对于像该网络这样的公司环境而言),如果没有在IE中设置任何自定义代理设置(通常是由公司策略推动),则几乎无法执行任何操作。要利用这些代理设置,您想使用WebRequestCreator.BrowserHttp,它在发出请求时会自动使用浏览器的默认设置。

in the Microsoft docs可用的这两个客户端之间的差异表。我猜您正在使用BrowserHttp不支持的某些功能(例如设置自定义标头或读取原始响应正文)。

出于安全原因,您不能“询问”浏览器的代理设置是什么,也不能使用它们,因此这是一个棘手的情况。您可以按域甚至针对特定请求指定浏览器与客户端的处理(上面的同一页面描述了如何操作);在这种情况下,您可以只使用ClientHttp进行服务调用,而使用BrowserHttp进行S3调用,从而避免麻烦!

对于后续步骤,我将尝试这种方法。如果它不起作用,我会尝试将批发商切换到BrowserHttp ,只是看看它是否绕过了代理问题(几乎没有机会实际运行该应用程序,因为您可能正在使用ClientHttp-唯一的选择)。

从长远来看,您可能需要考虑对服务进行更改,以便仅浏览器HTTP的应用程序可以使用它们(这要求您在请求/响应中非常基础,但是仅使用浏览器Http可以保证您几乎可以在任何公司网络中工作。

答案 1 :(得分:2)

以信任模式运行可能是一种组策略,这将需要其AD管理员批准/将您的应用列入白名单。

我认为您面临的根本问题是代理服务器需要NTLM身份验证,并且无论出于何种原因,浏览器都拒绝向您的应用程序提供该上下文。

证明它是NTLM身份验证问题的一种方法是使用curl进行测试-通过代理使其获得要求,然后编码起来应该更容易一些。例如,以下卷曲将使您了解99%的Windows企业代理(假设代理位于proxy-host.corp:3128):

C:\> curl.exe -v --proxy proxy-host:3128 --proxy-user : --proxy-ntlm https://www.google.com

注意 --proxy-user :告诉curl使用当前用户会话来执行NTLM质询。

因此,如果您可以让客户端运行该程序,则至少可以确定NTLM是否有效,这只是让应用程序使用默认凭据执行NTLM挑战的问题(可能会或可能不会提供)通过浏览器会话)

答案 2 :(得分:0)

由于您将其描述为Silverlight应用程序,因此我假设您无法使用经典的浏览器代理故障排除功能(例如“将浏览器移至公共网络”或“尝试使用其他浏览器”)来隔离问题。< / p>

您应该尝试隔离代理服务器,并让客户使用所需的proxy-auth。

应用程序正在发出请求,但是它可能被透明代理拦截,或者结果可能来自您认为是Web服务器的地方。

在早期,401错误与web-auth严格相关,而407错误与proxy-auth有关。

在架构上,分离是一种便利,Web服务器可以同时具有Web服务器,代理和反向代理行为。

发生的情况是您的客户的环境正在建立到目标的Web连接,但是它从某些主机(可能是他们的网络,有时是提供商)接收到HTTP 407状态。几乎可以肯定,请求没有被转发。您的应用程序所驻留的HTTP客户端需要提供主机所需的凭据。公司的环境非常复杂,您的客户经常会说这是他们第一次听说(有些proxy-auth也是动态的或特定于目的地的)。

此外,在某些公司环境中,操作员将允许来自proxy-auth服务的临时或永久白名单。您应该看看他们是否能做到这一点,甚至是暂时的,以确认不会有其他问题。

最后,听起来您的应用程序可能不完全支持代理身份验证或它们在环境中使用的代理身份验证类型。