<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>hubflanger &#187; cross-domain scripting</title>
	<atom:link href="http://hubflanger.com/tag/cross-domain-scripting/feed/" rel="self" type="application/rss+xml" />
	<link>http://hubflanger.com</link>
	<description>adventures in code</description>
	<lastBuildDate>Mon, 29 Mar 2010 22:41:12 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<atom:link rel='hub' href='http://hubflanger.com/?pushpress=hub'/>
		<item>
		<title>Cross-Domain Scripting Voodoo</title>
		<link>http://hubflanger.com/cross-domain-scripting-voodoo/</link>
		<comments>http://hubflanger.com/cross-domain-scripting-voodoo/#comments</comments>
		<pubDate>Mon, 07 Jul 2008 03:19:44 +0000</pubDate>
		<dc:creator>Peng</dc:creator>
				<category><![CDATA[Actionscript]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[cross-domain scripting]]></category>

		<guid isPermaLink="false">http://hubflanger.com/?p=39</guid>
		<description><![CDATA[If you&#8217;re thinking of hosting your SWFs on a content delivery network to improve the performance of your Flash application, or attempting to load a third-party SWF hosted on another domain into your  application, be aware that loading and scripting SWFs from another domain posts a whole set of security issues, namely that of [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re thinking of hosting your SWFs on a content delivery network to improve the performance of your Flash application, or attempting to load a third-party SWF hosted on another domain into your  application, be aware that loading and scripting SWFs from another domain posts a whole set of security issues, namely that of Cross-Domain Scripting. Due to the Flash Player 9&#8217;s security sandbox, when you load a SWF from another domain into a SWF hosted on your domain, by default, you will not be able to operate on the child SWF without it specifically granting permission.</p>
<p>Before proceeding with this tutorial, I highly recommend that you to read the <a href="http://www.adobe.com/devnet/flashplayer/articles/flash_player_9_security.pdf">Adobe Flash Player 9 Security White Paper</a>. This 51-page document, although thorough in many aspects, unfortunately left out crucial details that one would need in order to successfully perform cross-domain scripting. Another indispensable reference would be Colin Moock&#8217;s <a href="http://www.amazon.com/Essential-ActionScript-3-0/dp/0596526946/ref=pd_bbs_sr_1?ie=UTF8&amp;s=books&amp;qid=1217209517&amp;sr=1-1" target="_blank"><em>Essential ActionScript 3.0</em></a>, in particular, Chapter 19 on <em>Flash Player Security Restrictions</em> and Chapter 28 on <em>Loading External Display Assets</em>.</p>
<p>Let&#8217;s get started!</p>
<p><span id="more-39"></span><br />
In this tutorial, we will load a SWF named <code>domainB.swf</code> from the domain <code>http://sub.hubflanger.com</code> into a SWF named <code>domainA.swf</code> located at <code>http://hubflanger.com</code>. In the Adobe Flash Player 9 security sandbox, a subdomain is treated like any domain separate from its parent domain, so cross-domain security policies apply. Here, we shall assume that <code>domainA.swf</code> does not have access to any of <code>domainB.swf</code>&#8217;s classes during compilation.</p>
<p><a href="http://hubflanger.com/demos/cross_domain_scripting/">View Demo</a></p>
<p><a href="http://github.com/hubflanger/CrossDomainScripting_Tutorial">Download Source Files</a></p>
<h3>1. Setting up your URL policy file</h3>
<p>The URL policy file named <code>crossdomain.xml</code> is located, by default, in the root directory of the target server (http://sub.hubflanger.com). This policy file gives the parent SWF permission to load the child SWF.</p>
<div class="codeblock">
<pre>&lt;?xml version="1.0" encoding="UTF-8" ?&gt;
&lt;cross-domain-policy&gt;
  &lt;allow-access-from domain="*" /&gt;
&lt;/cross-domain-policy&gt;</pre>
</div>
<h3>2. Examining domainB.fla</h3>
<p>In <code>domainB.fla</code>, the document class is linked to the class <code>com.hubflanger.crossdomain.DomainB</code>. In the constructor of the <code>DomainB</code> class, the <code>Security.allowDomain("*");</code> statement enables scripting of this SWF from another domain (in this case, &#8220;*&#8221; denotes any domain). The class also has a public method named <code>sayHello()</code> which we will call from <code>domainA.swf</code> when <code>domainB.swf</code> is loaded.</p>
<div class="codeblock">
<pre>package com.hubflanger.crossdomain
{
  import flash.text.TextField;
  import flash.display.MovieClip;
  import flash.system.Security;

  public class DomainB extends MovieClip
  {
    public var myText1:TextField;

    public function DomainB()
    {
      Security.allowDomain("*");
    }

    public function sayHello( str:String ):void
    {
      myText1.text = str;
    }
  }
}</pre>
</div>
<p>On the stage, a dynamic textField named <code>myText1</code> will display a text string passed to the <code>sayHello()</code> method.</p>
<p>In the library panel, a symbol named <code>innerClip</code> is linked to the class <code>com.hubflanger.crossdomain.InnerClip</code>. The <code>InnerClip</code> class has a public method named <code>sayHello()</code> which we will call from <code>domainA.swf</code> as well.</p>
<div class="codeblock">
<pre>package com.hubflanger.crossdomain
{
  import flash.text.TextField;
  import flash.display.MovieClip;

  public class InnerClip extends MovieClip
  {
    public var myText2:TextField;

    public function InnerClip()
    {
      //
    }

    public function sayInnerHello( str:String ):void
    {
      myText2.text = str;
    }
  }
}</pre>
</div>
<p>The <code>innerClip</code> symbol also contains a dynamic textField <code>myText2</code> which will display a text string passed to the <code>sayInnerHello()</code> method.</p>
<h3>2. Examining domainA.fla</h3>
<p>The <code>domainA.fla</code> is linked to the document class <code>DomainA</code>. To import <code>domainB.swf</code>&#8217;s classes into <code>domainA.swf</code>&#8217;s application domain at runtime, we use a <code>LoaderContext</code> object when issuing the request to load <code>domainB.swf</code>. This makes <code>domainB.swf</code>&#8217;s classes directly accessible to <code>domainA.swf</code>.</p>
<p>In the <code>initHandler()</code> listener, we reference the <code>DomainB</code> class by calling the <code>getDefinition()</code> method of the <code>Loader</code>&#8217;s <code>applicationDomain</code> property by passing in the classpath <code>com.hubflanger.crossdomain.DomainB</code>. We can then gain access to <code>domainB.swf</code>&#8217;s <code>sayHello()</code> method by casting the <code>Loader</code>&#8217;s content to the <code>DomainB</code> type.</p>
<p>Similarly, we gain a reference to the <code>InnerClip</code> class and then create an <code>InnerClip</code> instance via this reference. We then call the <code>sayInnerHello()</code> method belonging to this instance.</p>
<div class="codeblock">
<pre>package
{
  import flash.display.*;
  import flash.net.*;
  import flash.events.*;
  import flash.system.*;

  public class DomainA extends MovieClip
  {
	private static const PACKAGE:String = "com.hubflanger.crossdomain.";

    public function DomainA()
    {
      var loader:Loader = new Loader();
      loader.contentLoaderInfo.addEventListener( Event.INIT, initHandler );
      loader.contentLoaderInfo.addEventListener( IOErrorEvent.IO_ERROR, ioErrorHandler );
      loader.contentLoaderInfo.addEventListener( SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler );
      addChild(loader);

      var loaderContext:LoaderContext = new LoaderContext( false, ApplicationDomain.currentDomain );
      loaderContext.applicationDomain =  ApplicationDomain.currentDomain;
      loader.load( new URLRequest( "http://sub.hubflanger.com/crossdomain/domainB.swf" ), loaderContext );
    }

    private function initHandler( evt:Event ):void
    {
      var packagePath:String = "com.hubflanger.crossdomain.";

      var appDomain:ApplicationDomain = evt.target.applicationDomain;

      var domainBRef:Class = appDomain.getDefinition( PACKAGE + "DomainB" )  as  Class;
      var domainB:Object = domainBRef( evt.target.content );
      domainB.sayHello( "Hello World!" );

      var innerClipRef:Class = appDomain.getDefinition( PACKAGE + "InnerClip" )  as  Class;
      var innerClip:Object = new innerClipRef();
      innerClip.sayInnerHello( "Inner clip says Hello!" );
      addChild( innerClip as MovieClip );
    }

    private function ioErrorHandler( e:IOErrorEvent ):void
    {
      trace( e.text );
    }

    private function securityErrorHandler( e:SecurityErrorEvent ):void
    {
      trace( e.text );
    }
  }
}</pre>
</div>
<p>That&#8217;s it. I hope this tutorial helped to clarify the confusion surrounding the daunting task of Cross-Domain Scripting. Happy coding!</p>
]]></content:encoded>
			<wfw:commentRss>http://hubflanger.com/cross-domain-scripting-voodoo/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
