Using the Client to Bridge to External Services
SharePoint 2010 does not permit solutions running in the sandbox execution environment to communicate with external services. If you want to call an external service from server-side code, you need to deploy either a farm solution that runs with full trust or deploy a full-trust proxy that communicates with the service on behalf of sandboxed solutions. However, the client-side data access mechanisms in SharePoint do provide an alternative solution. You can deploy to the sandbox environment a solution that uses client-side, rather than server-side, logic to call services that reside in other domains.
Service Calls Across Domain Boundaries
When you implement your client-side logic in a Silverlight application, there are two approaches you can use to access services in other domains from the client. The first approach is to deploy a service facade, or proxy, to the domain that hosts your SharePoint server. This allows your Silverlight application to access the service within its own domain and avoids any cross-domain issues.
The second approach is to use the Silverlight application to access the external service directly. As described in RIA Technologies: Benefits, Tradeoffs, and Considerations, the domain that hosts the service must define a client access policy (clientaccesspolicy.xml) file that permits access from Silverlight clients across domain boundaries. The Silverlight External Service interface in the reference implementation demonstrates this by deploying a service to a different port (which constitutes a different domain) on the SharePoint server.
The client access policy must be located at the root of the Web site that hosts the service. In the reference implementation, this is the localhost:81 site. The following code example shows the client access policy for the VendorService in the reference implementation.
<?xml version="1.0" encoding="utf-8" ?> <access-policy> <cross-domain-access> <policy> <allow-from http-request-headers="SOAPAction"> <domain uri="http://*"/> </allow-from> <grant-to> <resource include-subpaths="true" path="/Vendor/"/> </grant-to> </policy> </cross-domain-access> </access-policy>
The client access policy stipulates who is allowed access and which resources they are allowed access to. In this example, callers are only permitted to access the Vendor subpath that hosts the service. It's good practice to limit the resources that you expose to cross-domain access.
Securing the Service
In the reference implementation, the VendorService service is secured using Windows authentication with transport-level security, which provides a balance between security and complexity. Because this is designed for a test environment, we use an unencrypted HTTP connection for the service. In a production environment this would provide an insufficient level of security and you should use an SSL connection. VendorService is installed by the Full-Trust Proxies for Sandboxed Solutions reference implementation, which is a prerequisite for the Client RI. The installer for the Client RI will automatically deploy the Full-Trust Proxies RI to your test environment.
In order to use transport-level security with Windows and Internet Information Services (IIS), you must enable Windows authentication for the web site that hosts the service, and you must configure Microsoft Internet Information Services (IIS) to support URL authorization. URL authorization is configured by default in Windows Server® 2008, but if you are using Windows 7 you will need to configure it manually. To do this, in the Turn Windows features on or off dialog, expand Internet Information Services, expand World Wide Web Services, expand Security, and then ensure URL Authorization is checked, as illustrated by the following image.
The service is installed to the Contoso Web site in IIS. You must use IIS Manager to configure authentication for the site. Ensure that Windows authentication is configured for the web site that hosts the service, as shown in the following image.
When the Full-Trust Proxies RI deploys the VendorService service, it also adds an authorization policy to the Web site that hosts the service. The installer achieves this by adding the following code to the Web.config file for the Contoso web site.
<system.webServer> <security> <authorization> <remove users="*" roles="" verbs="" /> <add accessType="Allow" roles="Administrators" /> <add accessType="Deny" users="?" /> <add accessType="Allow" users="SandboxSvcAcct" /> </authorization> </security> </system.webServer>
|SandboxSvcAcct is a managed account that runs the Microsoft SharePoint Foundation Sandboxed Code Service. This was configured in the Full-Trust Proxies RI, as this is the identity provided by the full-trust proxy when a sandboxed solution uses a full-trust proxy to call the service. This account is not relevant to the Client RI.|
As you can see, the policy allows members of the Administrators role and the SandboxSvcAcct user to access the service. In the Client RI, it's assumed that you will use a member of the Administrators group to browse the Silverlight External Service interface and therefore to access the service. However, you can amend the security policy to grant access to other groups or specific users, or to experiment with alternative authorization rules.
The WCF service proxy for the vendor service was generated by Visual Studio, by adding a service reference to the service at http://localhost:81/Vendor/Service.svc. Because the service was configured for transport authentication when we created the proxy, adding the service reference automatically creates the correct security policy. The following example shows the client configuration file for the vendor service.
<configuration> <system.serviceModel> <bindings> <basicHttpBinding> <binding name="BasicHttpBinding_IVendorServices" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647"> <security mode="TransportCredentialOnly" /> </binding> </basicHttpBinding> </bindings> <client> <endpoint address="http://localhost:81/Vendor/Service.svc" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IVendorServices" contract="VendorService.IVendorServices" name="BasicHttpBinding_IVendorServices" /> </client> </system.serviceModel> </configuration>
The service binding defines the security mode as TransportCredentialOnly. This instructs the WCF service to accept credentials over an unsecured HTTP connection. It should be emphasized that this approach is not appropriate for anything other than test environments. If you want to use transport-level security in a production environment, you should secure the transport with SSL encryption. Because the host web site is configured to use Windows authentication, the service will authenticate Windows credentials over the unsecured HTTP connection.
With these settings in place, the service is secured for access directly from the client (in the Client RI) and access through a full-trust proxy (in the Full-Trust Proxy RI). The Client RI approach passes the credentials of the current user to the service, which allows for more granular authorization rules. The Full-Trust Proxy RI instead uses a trusted subsystem model—the sandbox environment removes the identity of the current user, and the identity of the managed account that runs the Sandboxed Code Service is provided instead.