Silverlight clientaccesspolicy.xml 和 Azure 开发存储
我在理解 Silverlight 下载 clientaccesspolicy.xml 文件的情况时遇到一些麻烦。我对运行时环境有一些复杂的情况需要解释。
这是一个 Azure Web 应用程序,在开发结构中以完整 IIS 模式运行。定义了两个站点:App 和 Admin。由于它们都位于端口 :80 上,因此可以通过主机标头 app.dev.com 和 admin.dev.com 访问它们,这两个标头在我的 HOSTS 文件中都有指向 127.0.0.1 的条目。访问这两个客户端应用程序都工作正常。 Silverlight 加载并命中定义的 RIA 服务,没有问题。
当 Silverlight 客户端尝试从开发存储访问 blob 时,事情会变得棘手。 问题之前已经解释过,所以我不会太深入——底线,你不能把由于开发存储的工作原理,XML 文件位于 Web 根目录中(它位于 http:// 127.0.0.1:10000/devstoreaccount1/clientaccesspolicy.xml)。解决方案是使用反向代理来重新映射 URL - 我已经使用 Fiddler 规则完成了此操作。其作用是“如果请求传入 127.0.0.1:11000,则将该请求修改为 :10000 并改为 GET”,等等。
if (oSession.host == "127.0.0.1:11000") {
oSession.host = "127.0.0.1:10000";
}
if (oSession.url == "127.0.0.1:10000/clientaccesspolicy.xml") {
oSession.url = "127.0.0.1:10000/devstoreaccount1/clientaccesspolicy.xml";
}
就重新映射而言,这是有效的;我可以在浏览器中点击 http://127.0.0.1:11000/clientaccesspolicy.xml 并获取该文件实际上位于 127.0.0.1:10000/devstoreaccount1/clientaccesspolicy.xml:
<?xml version="1.0" encoding="utf-8"?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from http-methods="*" http-request-headers="*">
<domain uri="*" />
</allow-from>
<grant-to>
<resource path="/" include-subpaths="true" />
</grant-to>
</policy>
</cross-domain-access>
</access-policy>
然后从 http://app.dev.com:81/default.aspx (提醒您,在 HOSTS 中重新映射到 127.0.0.1),
private void DownloadFile()
{
var sampleUri = new Uri("http://127.0.0.1:11000/devstorageaccount1/mycontainer/myblob.bin");
var client = new WebClient();
client.OpenReadCompleted += blobDownloaded;
client.OpenReadAsync(sampleUri);
}
void blobDownloaded(object sender, OpenReadCompletedEventArgs e)
{
if (e.Error != null) throw e.Error;
//throws
}
但有异常
System.Security.SecurityException ---> System.Security.SecurityException: Security error.
at System.Net.Browser.BrowserHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult)
at System.Net.Browser.BrowserHttpWebRequest.<>c__DisplayClass5.<EndGetResponse>b__4(Object sendState)
at System.Net.Browser.AsyncHelper.<>c__DisplayClass2.<BeginOnUI>b__0(Object sendState)
在 Fiddler 中查看,clientaccesspolicy.xml 文件不是下载了!我不知道为什么,或者如何调试它。我可以从浏览器下载该 blob。谁能解释一下为什么在下载 XML 文件之前就会抛出这个错误?
然后我尝试更新那些 Fiddler 规则:
if (oSession.host == "app.dev.com:10000") {
oSession.host = "127.0.0.1:10000";
}
if (oSession.url == "127.0.0.1:10000/clientaccesspolicy.xml") {
oSession.url = "127.0.0.1:10000/devstoreaccount1/clientaccesspolicy.xml";
}
并将下载的 URL 更改为
var sampleUri = new Uri("http://app.dev.com:10000/devstorageaccount1/mycontainer/myblob.bin");
这个成功了! Fiddler 捕获显示首先下载的 clientaccesspolicy.xml 文件,然后是 blob。
谁能帮忙解释一下这是怎么回事?在这两种情况下,Silverlight 应用程序均通过 http://app.dev.com:81/default 进行访问.aspx。当它尝试从 http://127.0.0.1:11000 下载 blob 时,它会失败并出现 SecurityException 无需首先下载clientaccesspolicy.xml。但是,当它从 http://app.dev.com:10000 下载 blob 时,它会成功,首先下载clientaccesspolicy.xml 和 blob。
感谢您的帮助,这个问题让我很困惑。
I am having some troubles with understanding the circumstances under which Silverlight downloads a clientaccesspolicy.xml file. I have a few complications to the runtime environment that need explaining.
This is an Azure web app, running in full IIS mode in dev fabric. There are two sites defined, App and Admin. Since they are both on port :80, they are accessed via host headers, app.dev.com and admin.dev.com, both of which have entries in my HOSTS file pointing back to 127.0.0.1. Accessing both of the client apps is working fine. Silverlight loads, and hits the RIA services defined, no problem.
Things get tricky when the Silverlight client tries to access a blob from dev storage. The problem has been explained before so I won't go too deep--bottom line, you can't put the XML file in the root of the web because of how dev storage works (it goes to http://127.0.0.1:10000/devstoreaccount1/clientaccesspolicy.xml). The solution is a reverse proxy to remap the URL--I've done it with a Fiddler rule. What this does is "if a request comes in for 127.0.0.1:11000, modify that request to :10000 and GET that instead," etc.
if (oSession.host == "127.0.0.1:11000") {
oSession.host = "127.0.0.1:10000";
}
if (oSession.url == "127.0.0.1:10000/clientaccesspolicy.xml") {
oSession.url = "127.0.0.1:10000/devstoreaccount1/clientaccesspolicy.xml";
}
This works as far as remapping is concerned; I can hit http://127.0.0.1:11000/clientaccesspolicy.xml in my browser and get the file actually living at 127.0.0.1:10000/devstoreaccount1/clientaccesspolicy.xml:
<?xml version="1.0" encoding="utf-8"?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from http-methods="*" http-request-headers="*">
<domain uri="*" />
</allow-from>
<grant-to>
<resource path="/" include-subpaths="true" />
</grant-to>
</policy>
</cross-domain-access>
</access-policy>
Then this fails from a Silverlight client accessed at http://app.dev.com:81/default.aspx (which to remind you, is remapped to 127.0.0.1 in HOSTS)
private void DownloadFile()
{
var sampleUri = new Uri("http://127.0.0.1:11000/devstorageaccount1/mycontainer/myblob.bin");
var client = new WebClient();
client.OpenReadCompleted += blobDownloaded;
client.OpenReadAsync(sampleUri);
}
void blobDownloaded(object sender, OpenReadCompletedEventArgs e)
{
if (e.Error != null) throw e.Error;
//throws
}
with exception
System.Security.SecurityException ---> System.Security.SecurityException: Security error.
at System.Net.Browser.BrowserHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult)
at System.Net.Browser.BrowserHttpWebRequest.<>c__DisplayClass5.<EndGetResponse>b__4(Object sendState)
at System.Net.Browser.AsyncHelper.<>c__DisplayClass2.<BeginOnUI>b__0(Object sendState)
Looking in Fiddler, the clientaccesspolicy.xml file was NOT downloaded! I have no idea why, or how to debug it. I can download the blob from my browser. Can anyone explain why this would throw before even downloading the XML file?
Then I tried updating those Fiddler rules:
if (oSession.host == "app.dev.com:10000") {
oSession.host = "127.0.0.1:10000";
}
if (oSession.url == "127.0.0.1:10000/clientaccesspolicy.xml") {
oSession.url = "127.0.0.1:10000/devstoreaccount1/clientaccesspolicy.xml";
}
and changing the URL to download to
var sampleUri = new Uri("http://app.dev.com:10000/devstorageaccount1/mycontainer/myblob.bin");
And this one succeeds! The Fiddler capture shows the clientaccesspolicy.xml file downloaded first and the blob second.
Can anyone help explain what's going on here? In both cases the Silverlight app is being access at http://app.dev.com:81/default.aspx. When it tries to download a blob from http://127.0.0.1:11000 it fails with a SecurityException without first downloading clientaccesspolicy.xml. But when it downloads a blob from http://app.dev.com:10000 it succeeds, first downloading clientaccesspolicy.xml and then the blob.
Thanks for the help, this one has me stumped.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
到 127.0.0.1 的流量通常会跳过代理,所以我想 Fiddler 根本没有机会重写 URL。您或许可以将 Silverlight 指向 ipv4.fiddler 并使其正常工作。
Traffic to 127.0.0.1 usually skips the proxy, so I would imagine Fiddler simply wasn't getting the chance to rewrite the URL. You could probably point Silverlight at ipv4.fiddler instead and get it to work.