We have seen that all accesses from Silverlight application
out of the domain are forbidden by default. However it is necessary to allow
accesses from other domains in some situations.
Actually at the access to a resource from other domain, Silverlight
Runtime checks if "clientaccesspolicy.xml" file which should be in a
root of the given domain exists. If this file is found, parameters of the
access to this domain are set in it.
If the file is not found, attempt of search of
"crossdomain.xml" file, which is necessary for Adobe Flash
applications work, will be made. If both files are not found, the access to the
domain is blocked outside.
To understand how it works, let us make some experiments.
For this purpose we need to create some websites that work in different
domains. For our experiment, such sites can be defined in a "hosts"
file which is located in a "%windir %\System32\drivers\etc" folder.
For example, it is possible to define this file as follows.
Listing 4 - The "host" file sample
127.0.0.1 site1.com
127.0.0.1 api.site1.com
127.0.0.1 subdomain.api.site1.com
127.0.0.1 site2.com
127.0.0.1 site3.com
From this listing we can see that we define some domains
which refer to local IP-address. It is now necessary to create in some sites in
IIS for each of the domains.
Let us place a file "data.xml" on a web-site
"api.site1.com" and we will create small Silverlight application
which will access this file. There will be some lines of a code which load a
XML-file in an asynchronous mode to this application.
Listing 5 - Sample
of Silverlight application
private void GetDataButton_Click(object sender, RoutedEventArgs e)
{
var client = new WebClient();
client.DownloadStringCompleted += client_DownloadStringCompleted;
client.DownloadStringAsync(new Uri(ServerURI.Text));
Data.Text = "Loading..";
}
void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
if (e.Error == null)
{
Data.Text = e.Result;
}
else
{
Data.Text = "Error: " + e.Error.ToString();
}
}
Let us place this application in each domain and try to
access to service. Now applications in all domains, except api.site1.com, will
throw a SecurityException.
To resolve cross-domain access to "api.site1.com"
the domain we will place "clientaccesspolicy.xml" within a web-site
"api.site1.com". Thus this file should have the address
"http://api.site1.com/clientaccesspolicy.xml". This file has the
following format.
Listing 6 - Sample of
"clientaccesspolicy.xml" file
<?xml version="1.0" encoding="utf-8" ?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from>
<domain uri="*" />
</allow-from>
<grant-to>
<resource path="/" include-subpaths="true" />
</grant-to>
</policy>
</cross-domain-access>
</access-policy>
When we place this file within the specified domain all
cross-domain access becomes possible and all applications from various domains
can access it. We can be sure that our Silverlight application has been
correctly set up if we can access our test application from the different domains
that we have previously deployed.
Besides, it is possible to adjust the policy so that access
is possible from only some domains. For example, the
"clientaccesspolicy.xml" file can look as follows.
Listing 7 - Sample of
"clientaccesspolicy.xml" file
<?xml version="1.0" encoding="utf-8" ?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from>
<domain uri="http://site1.com/" />
<domain uri="http://site2.com/" />
</allow-from>
<grant-to>
<resource path="/" include-subpaths="true" />
</grant-to>
</policy>
</cross-domain-access>
</access-policy>
In this case we allow access only from domains site1.com and
site2.com.
In other case we can define not only certain domains, but
also subdomains.
Listing 8 - Sample of
"clientaccesspolicy.xml" file
<?xml version="1.0" encoding="utf-8" ?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from>
<domain uri="http://*.site1.com/" />
</allow-from>
<grant-to>
<resource path="/" include-subpaths="true" />
</grant-to>
</policy>
</cross-domain-access>
</access-policy>
In this case access is possible from all subdomains
*.site1.com.
Also it is possible to limit which port and protocol will be
used. For example, we will allow access only via HTTPS for all sites.
Listing 9 - Sample of "clientaccesspolicy.xml"
file
<?xml version="1.0" encoding="utf-8" ?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from>
<domain uri="https://*" />
</allow-from>
<grant-to>
<resource path="/" include-subpaths="true" />
</grant-to>
</policy>
</cross-domain-access>
</access-policy>
Besides, it is possible to limit a set of resources which
are accessible from outside of current domain. For example, it is possible to
specify that only the "data.xml" file can be accessible out of the
domain.
Listing 10 - Sample of
"clientaccesspolicy.xml" file
<?xml version="1.0" encoding="utf-8" ?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from>
<domain uri="*" />
</allow-from>
<grant-to>
<resource path="data.xml" include-subpaths="false" />
</grant-to>
</policy>
</cross-domain-access>
</access-policy>
Besides, it is possible to demand HTTP-heading presence in
request.
In this case cross-domain access is allowed only in case of
this header presence.
Listing 11 - Sample of
"clientaccesspolicy.xml" file
<?xml version="1.0" encoding="utf-8" ?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from http-request-headers="SOAPAction">
<domain uri="*" />
</allow-from>
<grant-to>
<resource path="/" include-subpaths="true" />
</grant-to>
</policy>
</cross-domain-access>
</access-policy>
Undoubtedly such permission of access to the domain can have
the consequence of reducing security of a resource. It is possible to give
access to the inattentive application. That is why all web-services which
should be accessible to other domains are frequently taken in a separate
domain. For example, our application can work within "site1.com"
domain, and web-services within "api.site1.com" domain. Thus we can
save us from the attack that uses cookie of the user.