搜尋部落格文章

顯示具有 crossdomain 標籤的文章。 顯示所有文章
顯示具有 crossdomain 標籤的文章。 顯示所有文章

2013年2月5日 星期二

[轉] 圖片安全性操作解決方法

AS3 - Load a Remote Image from Any URL / Domain with No Stupid Security Sandbox Errors

Friday, September 18, 2009 by Sean P

Issue:

You want to load an image from an unkown external URL. It works on your computer... Sandbox Security error online (and/or the annoying images just showing up as solid white feature).
By default, Flash wants a crossdomain.xml file on the server you are loading from, but let's say there is none, because it's probably not your website.  Well, then the flash player isn't going to let you take that data and do what you want with it.
Attempting to do so will give you some error similar to:
*** Security Sandbox Violation ***
SecurityDomain 'http://www.designercolin.com/temp/ispire/get_boards.php' tried to access incompatible context 'somewebsite.com/someImage_here.jpg'

Half-Solution (aka the adobe way):

According to adobe's docs you need to do a couple things to work around this (to not access this remote data directly)- bypass policy file, and don't manipulate it in any way (ahem-lame).  See the next solution if you need to access or smooth the bitmap data.
1)  Use a LoaderContext instance with checkPolicyFile=false - this will tell it not to worry about the cross-domain issue and use the loader context object as 2nd parameter in Loader.load() call
var lc:LoaderContext = new LoaderContext();
lc.checkPolicyFile = false; // bypass security sandbox / policy file - does this effect quality when scaling? 

_myLoader = new Loader();
_myLoader.contentLoaderInfo.addEventListener(Event.INIT, onImageLoaded);

// load new url
_myURLRequest = new URLRequest($url);
_myLoader.load(_myURLRequest, lc);

2) Show the loaded image - This is where you may get the error (this is what had me pulling my hair out) 
Even with the checkPolicyFile = false set, I had to add the loader to a SPRITE (not movieclip, and not the loader content!), as this would be accessing data outside the sandbox
private function onImageLoaded($e:Event):void
{
  _innerImage = this.addChild(new Sprite());
  //_innerImage.addChild($e.currentTarget.content); // doesn't work. sandbox security error 
  _innerImage.addChild(_myLoader);
}
...by doing this, you will not have accessed this image data in any way to get the error, so you can load the image data but if you need to access the bitmapdata directly (or create a movie clip apparently?), I don't think it will work.
I'm not sure exactly why adding to a Sprite() instead of MovieClip() allowed it to work for me, they both are DisplayObjects, maybe there is something in the MovieClip constructor that accesses the image data... Whatever, it's stupid that you have to do that in the first place, so why would the method make sense!  See the other / better solution below..

Quality Question- for remote image data without policy file:

What I really want to know is (for printing purposes) - using this method, since there is no access directly to the image data, when you scale the image... does it not render with smoothing / anti-aliasing?  Is it poor quality outside of native dimensions?  Or is it basically the same quality as scaling a local image within security domain?  Final conclusion is that it's better to use a proxy if the image has to be anything but native (original size/scale)...

Better Solution- Go Around It

Well, since flash is finicky and now has had different bugs with different flash player versions, the smart thing to do is cut your losses and just go around this issue.  A local .php file or similar service as a proxy to cross-domains URLs will do the trick and retrieve the images and flash will basically think they were hosted locally.
Then, in flash you should set up a class that will prefix URLs for you, maybe extend the URLLoader...
However you do it, you want to prefix remote URLs with your proxy URL, and pass along the intended URL something like:
http://www.YourFlashSite.com/proxy/getimage.php?url=http://someOtherWebsite.com/someImage.jpg
On creating the PHP proxy to retrieve the file.. theres a few you can find with google but i have had issues with the majority of them-
One common proxy issue with Flash is that if your progressEvent.bytesTotal is 0 (making your preloader show Infinity) it may be because your server has gzip enabled.  You can use an app like Charles to see what your http activity looks like and see if there is gzip compression on the responses... turn off gzip for your proxy file and you're golden.

2012年3月30日 星期五

URL 原則檔範圍

URL 原則檔僅套用於載入的目錄及其子目錄。根目錄中的原則檔會套用至整個伺服器,但從任意子目錄載入的原則檔則僅套用於該目錄及其子目錄。

原則檔只影響它所在的特定伺服器。例如,位於 https://www.adobe.com:8080/crossdomain.xml 的原則檔案,只適用於在連接埠 8080 上透過 HTTPS 對 www.adobe.com 進行的資料載入呼叫。

在 URL 原則檔中指定存取權限

原則檔中包含單獨一個 標籤,其中再包含零個或多個 標籤。每一個 標籤中都包含一個特質,即 domain,它指定了確實的 IP 位址、確實的網域,或者萬用字元網域 ( 任何網域)。萬用字元網域會以下列兩種方式的其中一種指示:
• 使用單一星號 (*),與所有網域和所有 IP 位址相符
• 使用星號之後再加字尾,只比對找出以指定字尾結束的網域
字尾必須用一點為開頭。然而,有字尾的萬用字元網域可比對找出只含有該字尾而沒有最前端一點的網域。例如,xyz.com 被視為屬於 *.xyz.com 的一部分。在 IP 網域規格中不允許萬用字元。


下面是一個 URL 原則檔的範例,允許存取源自 *.example.com、www.friendOfExample.com 和 192.0.34.166 的 SWF
檔:







如果指定了一個 IP 位址,則只允許使用 IP 語法 ( 例如 http://65.57.83.12/flashmovie.swf) 從該 IP 位址載入的 SWF 檔進行存取,使用網域名稱語法載入的 SWF 檔則無法存取。Flash Player 不會執行 DNS 解析。
您可以允許存取源自任何網域的文件,如下列範例所示:






每個 標籤也都有選擇性的 secure 特質,此特質預設為 true。如果原則檔是位於 HTTPS 伺服器上,而您想要讓位於非 HTTP 伺服器上的 SWF 檔可以透過 HTTPS 伺服器載入資料,則您可以將此特質設為 false。
將 secure 特質設為 false 有可能會破壞 HTTPS 所提供的安全性。尤其是此特質設定為 false,將會讓安全性內容門戶洞開而遭受窺探與攻擊。Adobe 強烈建議您不要將 secure 特質設定為 false。
如果要載入的資料位於 HTTPS 伺服器上,但載入端 SWF 檔位於 HTTP 伺服器上,Adobe 建議您將載入端 SWF 檔移到HTTPS 伺服器上。如此一來,就可以讓您所有的安全資料都在 HTTPS 的保護之下。但是,如果您決定必須將載入端 SWF檔放在 HTTP 伺服器中,請將 secure="false" 特質加入至 標籤,如下列程式碼所示:


另一個您可以用來准許存取的元素是 allow-http-request-headers-from 標籤。這個元素會授與用戶端權限,從另一個網域裝載內容,以傳送使用者定義的檔頭到您的網域。 標籤可以授與其他網域權限從您的網域拉出資料,而 allowhttp-request-headers-from 標籤則是授與其他網域權限推入資料到您的網域,以檔頭的形式進行。在下列範例中,任何網域都准許傳送 SOAPAction 檔頭到目前的網域:



如果 allow-http-request-headers-from 陳述式是在主原則檔中,它會套用於主機上的所有目錄。否則,僅套用於包含該陳述式之原則檔的目錄及其子目錄。

Flash安全性 網站控制 ( 原則檔)

若要提供您網站伺服器的資料給另一個網域中的 SWF 檔使用,可以在伺服器中建立原則檔。「原則檔」是放置於您伺服器上特定位置中的 XML 檔。

原則檔會影響一些資源的存取,包括下列項目:
• 點陣圖、聲音和視訊中的資料
• 載入 XML 和文字檔
• 從其它安全網域將 SWF 檔匯入載入端 SWF 檔的安全網域
• 存取通訊端和 XML 通訊端連線

ActionScript 物件會實體化兩種不同的伺服器連線:文件架構伺服器連線和通訊端連線。ActionScript 物件 ( 如 Loader、Sound、URLLoader 和 URLStream) 會實體化文件架構伺服器連線,這些物件都會從 URL 載入檔案;ActionScript Socket和 XMLSocket 物件會建立通訊端連線,這是以串流資料而不是以載入的文件運作。

由於 Flash Player 支援兩種伺服器連線,因此有兩種原則檔:URL 原則檔和通訊端原則檔。
• 文件架構連線需要「URL 原則檔」。這些檔案可以讓伺服器指出其資料和文件可供 SWF 檔使用,從特定網域或所有網域提供服務。
• 通訊端連線需要「通訊端原則檔」,以便使用 Socket 和 XMLSocket 類別,直接在較低的 TCP 通訊端層級啟用網路作業。
Flash Player 需要使用與嘗試連線所要使用的相同通訊協定來傳輸原則檔。例如,將原則檔置於 HTTP 伺服器中時,來自其它網域的 SWF 檔就允許以它為 HTTP 伺服器載入資料,但是,如果不在相同伺服器上提供通訊端原則檔,就必須禁止來自其它網域的 SWF 檔,在通訊端層級連線至伺服器。換句話說,擷取原則檔的工具必須與連線的工具相符。