0

I'm having some strange inter-domain loading behaviour. I need to give my loading swf access to my loaded swf's classes and methods across domains, but despite all my applicationDomain settings and cross domain settings, I'm not being able to cast it to a usable type across domains, but it works perfectly same domain.

The scenario:

Application on domain A loads a skin from domain B (actually all part of a massive domain structure (test.domain.co.uk, assets.domain.co.uk, etc), but for Flash's purposes they are different). Currently some of the files are on a testing environment and will move through several environments before it goes live, so I'm keeping all security calls relatively loose. There are crossdomain.xml files all over the place.

the loading code:

_skinLoader = new Loader();
addChild(_skinLoader);
var context:LoaderContext = new LoaderContext();
context.applicationDomain = new ApplicationDomain(ApplicationDomain.currentDomain);
_skinLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, skinError, false, 0, true);
_skinLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, skinLoaded);
var skinurl:String = "http://www.domainB/skins/skin.swf";
var request : URLRequest = new URLRequest(skinurl);
_skinLoader.load(request, context);

the COMPLETE event code:

onSkinLoaded(e:Event):void{
   addChild(_skinLoader);
   _skin = e.currentTarget.content as ISkin;

   trace("SHELL: Skin loaded:"+_skin); //======== traces out null when x-domain but traces out[object SkinObject] on the same domain or in the IDE
   trace("SHELL: Skin target:"+e.currentTarget.content); //===== traces out [object SkinObject] on both
   ...............

}

So it works when the skin is on the same domain as the shell application, but not when they are separate. As you may tell from the code above the skin implements ISkin and extends and abstract class ASkin; to deal with security I have the following as the constructor of the skin class (which is the base class of the fla).

public function SkinObject(){
     Security.allowDomain(this.root.loaderInfo.loaderURL);
     super();
}

Other info:

  • Traces in the skin constructor class fire
  • When the skin is on the same domain if I test (e.currentTarget.content is ISkin) I get true, when on separate domains, I get false
  • There are no security events
  • I have tried setting the loader context to new ApplicationDomain as well.
Sunya
  • 21
  • 1
  • 3

3 Answers3

2

Ok. I've discovered the answer on one of the brilliant senocular's pages: http://www.senocular.com/flash/tutorials/contentdomains/?page=1

Essentially the problem can be overcome by merging the Security Domains of the two swfs and to set the applicationDomain to the same. Below is a quote from the above page (example urls have a / in them to prevent them becoming links):

To load another SWF into the security domain of your own, you would need to call Loader.load with an instance of a LoaderContext object. The securityDomain property of that LoaderContext is set to a reference to the current security domain. This is accessible through SecurityDomain.currentDomain. In setting this value, the loader SWF expresses trust in the SWF that is to be loaded, while that SWF expresses trust through a policy file.

h/ttp://host.example.com/parent.swf:

trace(new LocalConnection().domain); // host.example.com

var loader:Loader = new Loader();

// create a LoaderContext that indicates that
// the loaded SWF will be loaded into this
// security domain
var context:LoaderContext = new LoaderContext(true);
context.securityDomain = SecurityDomain.currentDomain;

var url:String = "http://trusting.example.com/child.swf";
loader.load(new URLRequest(url), context);

h/ttp://trusting.example.com/crossdomain.xml:

<?xml version="1.0"?> 
<cross-domain-policy>
<allow-access-from domain="host.example.com"/>
</cross-domain-policy>

h/ttp://trusting.example.com/child.swf:

trace(new LocalConnection().domain); // host.example.com

Using the domain property of a LocalConnection instance, the security domain is checked for each SWF. Though the child SWF originated from the trusting.example.com domain, it's shown as being within the host.example.com domain because the parent SWF loaded it into its own security domain.

I hope that helps someone from spending 3 days going around and around in circles. Thank you senocular!

Community
  • 1
  • 1
Sunya
  • 21
  • 1
  • 3
  • In order to be clear about this problem as opposed to simply loading in and scripting a swf across domains; here the swf being loaded across domains is using **the same classes as the loading swf**. The child swf comes from another domain meaning that flash doesn't allow it to have the same classes as the parent. This meant that I couldn't cast the loaded swf to the interface which it implements (design patterns!). Hence merging security domains and application domains outlined above. It may also work to cast loaded swfs to a more generic class that exists in the system domain like an object. – Sunya Sep 28 '11 at 13:52
1

This line of code will not do what you expect it to:

Security.allowDomain(this.root.loaderInfo.loaderURL);

I'm pretty sure that the root URL of the swf you're loading from domain B to A will still be domain B, otherwise the crossdomain policy system wouldn't even work in the first place, because any/all swfs loaded from X domain to A domain would automatically become a child of domain A (with this logic).

You need to write a crossdomain policy file and place it in both domain A and domain B giving explicit permission for domain B to interact with A, and A with B. Here is an example of a crossdomain policy file that will grant permission to anyone loading the swfs in the domain.

<?xml version="1.0" ?>
<cross-domain-policy>
<allow-access-from domain="*" />
</cross-domain-policy>

Taken from this question/answer:

Can someone post a well formed crossdomain.xml sample?

Community
  • 1
  • 1
  • Hi, Thanks for the reply. That line of code in the constructor of the the skin in domain B gives: `SKIN:::: You are loading from:http://test.domainA.co.uk/source/swfa.swf`. I have a crossdomain.xml that contains this line `` – Sunya Sep 21 '11 at 15:32
  • Added to which, `Security.allowDomain("*");` doesn't help. I think the point of main interest is that the swf IS being loaded - the constructor fires - but it cannot be cast to ISkin, which is the interface it implements. This makes me think that it is an ApplicationDomain issue. – Sunya Sep 21 '11 at 15:43
0

DomainA swf: When loading the swf from domainB is loading crossdomain.xml from domainB. if this will not help then:

inside SWF on DomainA add:

System.allowDomain ( 'DomainB' );

crossdomain.xml basicaly needed for images / videos and other type of files. Swf;s needs to be taked care sepparately:

inside SWF on DomainB add:

System.allowDomain ( 'DomainA' );
Jevgenij Dmitrijev
  • 2,228
  • 1
  • 15
  • 23
  • Thank you for your response. If you have a look at the code posted and the other answer, you'll see that I have both a crossdomain.xml and `Security.allowDomain(this.root.loaderInfo.loaderURL)`. I have also tried `Security.allowDomain("*")`. **I am able to load the swf**, but _I can't cast it to the interface that it implements_ – Sunya Sep 21 '11 at 16:11
  • ohh missed that... have you tryied `e.currentTarget.content as ASkin`? – Jevgenij Dmitrijev Sep 21 '11 at 16:29
  • Hi, yes I have tried that. I'm now convinced that the issue is to do with the ApplicationDomain. I have been tracing out `e.currentTarget.content is ISkin`; on the same domain I get true and x-domain I get false. If I set the loader context to new ApplicationDomain, I can get the same domain output to return false to the same statement. **So I guess the question is:** _How do I get content loaded from a different security domain to behave as same ApplicationDomain, if the above code doesn't do it?_ – Sunya Sep 22 '11 at 08:42
  • i looked how i'm using it: `context = new LoaderContext(false, ApplicationDomain.currentDomain);` `false` specifies to skip looking for policy file, that might be your case. – Jevgenij Dmitrijev Sep 22 '11 at 09:00