See how Microsoft Consulting Services can help you
Contact Microsoft Services
Contact The SharePoint Guys
Apply for a job at Microsoft Consulting Services
MCS Solution Dev
The Deployment Guys
MSDN UK
MSDN UK Newsletter
MSDN UK Team Blog
TechNet UK
TechNet UK Newsletter
TechNet UK Blog
I’ve recently been working on a project where a Silverlight App sitting on a separate url calls through to a WCF service hosted in SharePoint. For this to work, a “clientaccesspolicy.xml” file is required at the root of the SharePoint web application. This file will contain the following:
1: <?xml version="1.0" encoding="utf-8"?>
2: <access-policy>
3: <cross-domain-access>
4: <policy>
5: <allow-from http-request-headers="SOAPAction">
6: <domain uri="*"/>
7: </allow-from>
8: <grant-to>
9: <resource path="/" include-subpaths="true"/>
10: </grant-to>
11: </policy>
12: </cross-domain-access>
13: </access-policy>
I have seen multiple approaches to this so far, as follows:
Note that scripting either approach into our deployments (and supporting multiple web-front ends) seemed to be quite complex, so instead I opted to write a feature receiver to deploy the file to the root of a web application on all web front ends. The steps for doing this are shown below (note that this does not just apply to the ClientAccessPolicy.xml file, but also any file that you want to deploy to the web application root directory).
1: using System;
2: using System.Collections.Generic;
3: using System.IO;
4: using Microsoft.SharePoint.Administration;
5: using Microsoft.SharePoint.Utilities;
6:
7: namespace SPClientAccessPolicy.Features.DeployClientAccessPolicy
8: {
9: public class ClientAccessPolicyDeploymentJob : SPJobDefinition
10: {
11: public ClientAccessPolicyDeploymentJob()
12: : base()
13: {
14: }
15:
16: public ClientAccessPolicyDeploymentJob(string jobName, SPService service, SPServer server, SPJobLockType targetType)
17: : base(jobName, service, server, targetType)
18: {
19: }
20:
21: public ClientAccessPolicyDeploymentJob(string jobName, SPWebApplication webApplication)
22: : base(jobName, webApplication, null, SPJobLockType.None)
23: {
24: }
25:
26: public override void Execute(Guid targetInstanceId)
27: {
28: var webApp = this.Parent as SPWebApplication;
29: foreach (KeyValuePair<SPUrlZone, SPIisSettings> setting in webApp.IisSettings)
30: {
31: var webRootPolicyLocation = setting.Value.Path.FullName + @"\clientaccesspolicy.xml";
32: var featuresPolicyLocation = SPUtility.GetGenericSetupPath(@"TEMPLATE\FEATURES\DeployClientAccessPolicy\ClientAccessPolicy\clientaccesspolicy.xml");
33: File.Copy(featuresPolicyLocation, webRootPolicyLocation, true);
34: }
35:
36: base.Execute(targetInstanceId);
37: }
38: }
39: }
2: using System.Runtime.InteropServices;
3: using Microsoft.SharePoint;
5:
6: namespace SPClientAccessPolicy.Features.DeployClientAccessPolicy
7: {
8: [Guid("fca183e0-3f93-47be-b28e-630c383d6e76")]
9: public class DeployClientAccessPolicyEventReceiver : SPFeatureReceiver
11: private const string JobName = "ClientAccessPolicyJob";
12:
13: public override void FeatureActivated(SPFeatureReceiverProperties properties)
14: {
15: var site = properties.Feature.Parent as SPWebApplication;
16: RemoveJobIfRegistered(site);
17:
18: var clientAccessPolicyJob = new ClientAccessPolicyDeploymentJob(JobName, site);
19: var schedule = new SPOneTimeSchedule(DateTime.Now);
20: clientAccessPolicyJob.Schedule = schedule;
21: clientAccessPolicyJob.Update();
22:
23: site.JobDefinitions.Add(clientAccessPolicyJob);
24: site.Update();
26: clientAccessPolicyJob.RunNow();
27: }
28:
29: public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
31: var site = properties.Feature.Parent as SPWebApplication;
32:
33: RemoveJobIfRegistered(site);
36: private void RemoveJobIfRegistered(SPWebApplication site)
37: {
38: foreach (SPJobDefinition job in site.JobDefinitions)
39: {
40: if (job.Title == JobName)
41: {
42: job.Delete();
43: }
44: }
45: }
46: }
47: }
Right click on the project to deploy. Your feature will deploy the ClientAccessPolicy.xml file to the root of your web application.
If you encounter any issues, try the following (in no particular order)…
When you have completed development, the solution should look similar to this…
For Silverlight, the clientaccesspolicy.xml file may require anonymous access. I was originally hoping to add this into the web.config via a SPWebConfigModification object ran on my feature receiver as follows:
1: <location path="clientaccesspolicy.xml">
2: <system.webServer>
3: <security>
4: <authentication>
5: <anonymousAuthentication enabled="true" />
6: </authentication>
7: </security>
8: </system.webServer>
9: </location>
This is not possible however, as the C:\Windows\System32\inetsrv\config\ApplicationHost.config file blocks overriding of anonymous authentication. To overcome this, we will need to alter the applicationhost.config on each web front end to permit anonymous access to this file.
I intent to post our findings / final implementation of this.
Rob Nowik Senior Consultant Microsoft Consulting Services UK ronowik@microsoft.com
Click here for my bio page