`
kennyluo
  • 浏览: 78222 次
  • 性别: Icon_minigender_1
  • 来自: 珠海
社区版块
存档分类
最新评论

Domain Locking SWFs

阅读更多
By domain locking (or site locking), we are restricting the SWF to be run only from a certain domain, ie the SWF should execute normally only if it has been viewed from a certain domain. If it is loaded from other domains, the SWF should execute in an alternative manner – perhaps not run at all, or run with limited features (as the developer deems appropriate). This is usually done to prevent unauthorized re-distributions of SWF files.


Which SWF URL?
We can get the URL of a SWF by checking the url property of the LoaderInfo object of the main document class:

var swfURL:String = loaderInfo.url;

However, for the purpose of domain locking, we would want to look at the loaderURL property instead:

var ldrURL:String = loaderInfo.loaderURL;

This is because your SWF can be loaded via a Loader object in another SWF, possibly from another domain. In this case, the url property still reports the URL of your SWF file (since it is still being loaded/leeched from the original location) but the loaderURL property will not be the same.

For a SWF that is loaded directly, both the url and loaderURL properties report the same value.


What About HTML Page URL?
It is possible that your SWF may be loaded directly from an allowed domain, and yet viewed within another unauthorized domain. This can happen if a HTML page from a different domain embeds your SWF object directly. If you wish to know the URL of the HTML page containing the SWF, you need to use the flash.external.ExternalInterface class:

import flash.external.ExternalInterface;
 
var htmlURL:String;
if (ExternalInterface.available)
{
	htmlURL = ExternalInterface.call("window.location.href.toString");
}

That will give you the URL of the HTML page containing the loaded SWF, which you can test against when domain locking SWFs.

However, this depends on ExternalInterface to be available, which means it will only work with the following browsers:
* IE 5.0 and later
* Firefox 1.0 and later
* Mozilla 1.7.5 and later
* Netscape 8.0 and later
* Safari 1.3 and later
* any other browser that supports the NPRuntime interface.

Where ExternalInterface is unavailable, you should fall back to checking against the loaderURL.

import flash.external.ExternalInterface;
 
var url:String;
if (ExternalInterface.available)
{
	url = ExternalInterface.call("window.location.href.toString");
}
else
{
	url = loaderInfo.loaderURL;
}

You may also, if you wish, assume that if ExternalInterface is not available, then your SWF is being viewed under the wrong conditions and therefore it should not continue running. If you decide to go this (rather extreme) route, do consider showing a message to let the end-users know why, possibly telling them where they should go to view your application and which browsers they can use.

On the other hand, it is also possible that you may not want to test against the HTML page URL for domain locking purposes at all. Perhaps you want to allow other websites to show your SWF as long as the SWF is loaded from your server. For example, this can be the case if you have a widget that you want other websites to use but do not want the SWF to be re-distributed outside your domain. In such cases, knowing the HTML page URL is nevertheless useful for other reasons, such as tracking sites displaying your SWF.

Ultimately, which URL you should test against depends on the needs of your application.


Domain Locking – Single Domain
Once you get the proper URL to check against, your code can test to see if it is “qualified”. If it doesn’t match a pre-defined criteria, you would abort the rest of your application code, or run the application with limited features.

Here is the code you can use:

var allowedDomain:String = "www.ghostwire.com";
 
var allowedPattern:String = "^http(|s)://"+allowedDomain+"/";
var domainCheck:RegExp = new RegExp(allowedPattern,"i");
if (!domainCheck.test(url))
{
    // domain check failed, abort application
    stop();
    // abort();
}
else
{
    // domain okay, proceed
}

    allowedDomain specifies the allowed domain
    allowedPattern is the regular expression pattern that would be used – basically it says (i) the URL must start with “http://” or “https://”, (ii) followed by the allowed domain, (iii) followed by a slash “/” immediately after the domain name.
    If you don’t expect your SWF to ever run via secured http, then the pattern can be “http://”+allowedDomain+”/”
    Likewise if you expect your SWF to always run via secured http, then change the pattern to “https://”+allowedDomain+”/”
    domainCheck is the RegExp object with pattern set to allowedPattern and using ignoreCase flag “i”.
    domainCheck.test(url) returns true if the url contains the allowed domain name at the correct position in the string, false otherwise.


Domain Locking – Multiple Domains
What if we want to allow multiple domain names? With a little tweak to the regular expression, we can specify multiple domains using “|” as delimiter, as shown below:

var allowedDomains:String = "ghostwire.com|somewhere.net|elsewhere.org";
 
var allowedPattern:String = "^http(|s)://("+allowedDomains+")/";
var domainCheck:RegExp = new RegExp(allowedPattern,"i");
if (!domainCheck.test(url))
{
    // domain check failed, abort application
    stop();
    // abort();
}
else
{
    // domain okay, proceed
}

    allowedDomains specifies one or more domain names to allow, with each domain name separated by alternator “|”.
    allowedPattern has been changed to support the group of domain names.
    This code works with single domain too.


Wild Cards
You can use regular expression wild cards when specifying allowedDomains:

var allowedDomains:String = ".*ghostwire.com";
// ghostwire.com and all subdomains

Likewise for multiple domains:

var allowedDomains:String = ".*ghostwire.com|.*somewhere.net|onlyhere.org";
// ghostwire.com and subdomains
// somewhere.net and subdomains
// onlyhere.org but none of its subdomains

There is no typo in the above – the dot (.) says match any character and the star (*) says zero or more matches.


Getting Domain Name
Let’s say you have allowed multiple domain names to run the SWF, but you would like to know which domain the SWF is loaded from. Perhaps your application may run with additional features if it is loaded from a certain domain. Whatever the reason may be, you can do so with the code below:

var allowedDomains:String = "ghostwire.com|somewhere.net|elsewhere.org";
 
var allowedPattern:String = "^http(|s)://(?P<name>"+allowedDomains+")/";
var domainCheck:RegExp = new RegExp(allowedPattern,"i");
var domainCheckResult:Object = domainCheck.exec(url);
if (domainCheckResult == null)
{
    // domain check failed, abort application
    stop();
    // abort();
}
else
{
    // domain okay, proceed
    trace(domainCheckResult.name) // the domain name
    // trace(domainCheckResult.name.toLowerCase()) // in lower case
}

    We have used a named group in the regular expression for easy access to the matched domain name. This is done using (?P and ) to define the named group.
    We use domainCheck.exec(url) instead of domainCheck.test(url) here.


Preventing SWFs From Running Locally
Because the pattern checks the URL to see if it starts with “http://” or “https://”, by domain locking you would also prevent the SWF from running locally (the URL will start with “file:///”).

If no domain locking is intended (ie, you want your SWF to be freely distributed and run online) but not run locally, you can use the following code:

var domainCheck:RegExp = new RegExp("^http(|s)://");
if (!domainCheck.test(url))
{
    // domain check failed, abort application
    stop();
    // abort();
}
else
{
    // domain okay, proceed
}

For other alternatives, see the post “Preventing SWFs From Running Locally”.
 
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics