How to: Create a custom proxy page for the cross-domain library in SharePoint 2013

apps for SharePoint

Learn how to create a custom proxy page to access data in a remote service from a SharePoint webpage by using the cross domain library in SharePoint 2013.

Last modified: May 30, 2014

Applies to: apps for SharePoint | Office 365 | SharePoint Foundation 2013 | SharePoint Server 2013

When you are building apps for SharePoint, you usually have to incorporate data from various sources. However, for security reasons, there are blocking mechanisms that prevent communication with more than one domain at a time.

You can use the cross-domain library to access data in your remote app if you provide a custom proxy page that is hosted in the remote app infrastructure. As the developer, you are responsible for implementing the custom proxy page, and have to deal with custom logic, such as the authentication mechanism to the remote app. Use the cross-domain library with a custom proxy page if you want the communication to occur at the client level.

To follow the steps in this example, you need the following:

  • Visual Studio 2012

  • Office Developer Tools for Visual Studio 2012

  • A SharePoint 2013 development environment (app isolation required for on-premises scenarios)

For guidance on how to set up a development environment that fits your needs, see Start building apps for Office and SharePoint.

Core concepts to know before using a custom proxy page with apps for SharePoint

The following table lists some useful articles that can help you understand the concepts involved in a cross-domain scenario for apps for SharePoint.

Table 1. Core concepts for using a custom proxy page

Article title

Description

Overview of apps for SharePoint

Learn about the new app model in SharePoint 2013 that enables you to create apps, which are small, easy-to-use solutions for end users.

Data access options for apps in SharePoint 2013

Learn about data access options in apps for SharePoint. This topic provides guidance on the high-level alternatives you have to choose from when working with data in your app.

Host webs, app webs, and SharePoint components in SharePoint 2013

Learn about the difference between host webs and app webs. Find out which SharePoint 2013 components can be included in an app for SharePoint, which components are deployed to the host web, which components are deployed to the app web, and how the app web is deployed in an isolated domain.

Client-side Cross-domain Security

Explore cross-domain threats and use cases, and security principles for cross-origin requests, and weigh the risks for developers to enhance cross-domain access from web applications that run in the browser.

To read data from the remote service, you must do the following:

  1. Create an app for SharePoint project and a web project in Visual Studio.

  2. Modify the app manifest to allow communication from the remote app.

  3. Create the custom proxy page and a content page in the web project.

  4. Create a page that uses the cross-domain library in the app for SharePoint project.

Figure 1 shows a SharePoint webpage with data from a remote service.

Figure 1. SharePoint page with data from a remote service

SharePoint page with data from a remote service

To create the app for SharePoint and remote web projects

  1. Open Visual Studio 2012 as administrator. (To do this, right-click the Visual Studio 2012 icon on the Start menu, and choose Run as administrator.)

  2. Create a new project using the App for SharePoint 2013 template.

    Figure 2 shows the location of the App for SharePoint 2013 template in Visual Studio 2012, under Templates, Visual C#, Office SharePoint, Apps.

    Figure 2. App for SharePoint 2013 Visual Studio template

    App for SharePoint 2013 Visual Studio template
  3. Provide the URL of the SharePoint website that you want to use for debugging.

  4. Select provider-hosted as the hosting option for your app.

    After the wizard finishes, you should have a structure in Solution Explorer that resembles Figure 3.

    Figure 3. App for SharePoint projects in Solution Explorer

    App for SharePoint projects in Solution Explorer

To edit the app manifest file

  1. In Solution Explorer, right-click the AppManifest.xml file, and choose View code.

  2. Copy the following the app principal definition, and substitute the default.

    <AppPrincipal>
        <Internal AllowedRemoteHostUrl="~remoteAppUrl"/>
    </AppPrincipal>
    
    NoteNote

    The AllowedRemoteHostUrl attribute is used to specify the remote domain. The ~remoteAppUrl resolves to the remote app URL. For more information about tokens, see Explore the app manifest and the package of an app for SharePoint.

To create a custom proxy page

  1. Right-click the web project in Solution Explorer, and add a new Web form.

  2. Copy the following markup and paste it in the ASPX file. The markup performs the following tasks:

    • Provides a placeholder for the cross-domain library JavaScript file.

    • Extracts the app web URL from the referrer.

    • Dynamically loads the cross-domain library JavaScript file into the placeholder.

    • Provides settings for the RequestExecutorMessageProcessor object.

    • Initializes the RequestExecutorMessageProcessor object.

    <!DOCTYPE html>
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <meta http-equiv="X-UA-Compatible" content="IE=8" /> 
        <title>Custom Proxy Host Page</title>
        <script 
            src="http://ajax.aspnetcdn.com/ajax/4.0/1/MicrosoftAjax.js" 
            type="text/javascript">
        </script>
        <script 
            type="text/javascript" 
            src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.2.min.js">
        </script>
    
        <!-- Script to load the cross-domain library js file -->
        <script type="text/javascript">
            var hostweburl;
    
            $(document).ready(function(){
                //Get the URI decoded host web URL.
                hostweburl =
                    decodeURIComponent(
                        getQueryStringParameter("SPHostUrl")
                );
    
                // The cross-domain js file is in a URL in the form:
                // host_web_url/_layouts/15/SP.RequestExecutor.js
                var scriptbase = hostweburl + "/_layouts/15/";
    
                // Load the js file 
                $.getScript(scriptbase + "SP.RequestExecutor.js", initCustomProxy);
            });
    
            //Function to initialize the custom proxy page
            //  must set the appropriate settings and implement
            //  proper authentication mechanism
            function initCustomProxy() {
                var settings =
                {
                    originAuthorityValidator: function (messageOriginAuthority) {
                        // This page must implement the authentication for the
                        //   remote app.
                           // You should validate if messageOriginAuthority is
                           //  an approved domain to receive calls from.
                        return true;
                    }
                };
                SP.RequestExecutorMessageProcessor.init(settings);
            }
    
            // Function to retrieve a query string value.
            // For production purposes you may want to use
            //  a library to handle the query string.
            function getQueryStringParameter(paramToRetrieve) {
                var params =
                    document.URL.split("?")[1].split("&");
                var strParams = "";
                for (var i = 0; i < params.length; i = i + 1) {
                    var singleParam = params[i].split("=");
                    if (singleParam[0] == paramToRetrieve)
                        return singleParam[1];
                }
            }
        </script>
    </head>
    <body>
        
    </body>
    </html>
    
    
    
    Important noteImportant

    You must provide the authorization logic and return the appropriate value in the originAuthorityValidator object in settings.

To create a content page

  1. Right-click the web project in Solution Explorer, and add a new Web form.

  2. Copy the following code and paste it in the Page_Load method in the code-behind file. The code performs the following tasks:

    • Sets the output content-type to text/plain.

    • Writes the content to the output buffer.

    • Ends the connection.

    string content;
    content = "Just some text.";
    Response.ContentType="text/plain";
    Response.Write(content);
    Response.End();
    
    

To create a SharePoint webpage that uses the cross-domain library

  1. Open the Home.aspx page in the app for SharePoint project.

  2. Copy the following code and paste it in the PlaceHolderMain content tag. The code performs the following tasks:

    • Sets the output content-type to text/plain.

    • Writes the content to the output buffer.

    • Ends the connection.

    <!-- The page dynamically loads the cross-domain library's
        js file, rescript acts as the placeholder. -->
    <script 
        type="text/javascript"
        id="rescript"
        src="../_layouts/15/SP.RequestExecutor.js">
    </script>
        Data from the remote domain: <span id="TextData"></span>
    
        <!-- Main script to retrieve the host web's title -->
        <script type="text/javascript">
        (function () {
            var executor;
            var hostweburl;
            var remotedomain;
    
            remotedomain = "<your_remote_app_domain>;
    
            //Get the URI decoded host web URL.
            hostweburl =
                decodeURIComponent(
                    getQueryStringParameter("SPHostUrl")
            );
    
            // Initialize the RequestExecutor with the custom proxy URL.
            executor = new SP.RequestExecutor(remotedomain);
            executor.iFrameSourceUrl = "CustomProxy.aspx?SPHostUrl=" + hostweburl;
    
            // Issue the call against the remote endpoint.
            // The response formats the data in plain text.
            // The functions successHandler and errorHandler attend the
            //      sucess and error events respectively.
            executor.executeAsync(
                {
                    url:
                        remotedomain + "SimpleContent.aspx",
                    method: "GET",
                    headers: { "Accept": "text/plain" },
                    success: successHandler,
                    error: errorHandler
                }
            );
        })();
    
        // Function to handle the success event.
        // Prints the data to the placeholder.
        function successHandler(data) {
            document.getElementById("TextData").innerText =
                data.body;
        }
    
        // Function to handle the error event.
        // Prints the error message to the page.
        function errorHandler(data, errorCode, errorMessage) {
            document.getElementById("TextData").innerText =
                "Could not complete cross-domain call: " + errorMessage;
        }
    
        // Function to retrieve a query string value.
        // For production purposes you may want to use
        //  a library to handle the query string.
        function getQueryStringParameter(paramToRetrieve) {
            var params =
                document.URL.split("?")[1].split("&");
            var strParams = "";
            for (var i = 0; i < params.length; i = i + 1) {
                var singleParam = params[i].split("=");
                if (singleParam[0] == paramToRetrieve)
                    return singleParam[1];
            }
        }
        </script>
    
    

To build and run the solution

  1. Make sure that the app for SharePoint project is set as the startup project.

  2. Press the F5 key.

    Note Note

    When you press F5, Visual Studio builds the solution, deploys the app, and opens the permissions page for the app.

  3. Choose the Trust It button.

  4. Click the app icon on the Site Contents page.

    Figure 3 shows the remote service data in a SharePoint webpage.

    Figure 3. Data from the remote service in a SharePoint webpage

    SharePoint page with data from a remote service
Table 2. Troubleshooting the solution

Problem

Solution

Visual Studio does not open the browser after you press the F5 key.

Set the app for SharePoint project as the startup project.

Unhandled exception SP is undefined.

Make sure that you can access the SP.RequestExecutor.js file in a browser window.

This article demonstrated how to access remote data by using a custom proxy page for the cross-domain library in SharePoint 2013. As a next step, you can learn about other data access options available in apps for SharePoint. To learn more, see the following:

Show:
© 2014 Microsoft