Try our conversational search powered by Generative AI!

Configuring Web Services Authentication

Product version:

EPiServer CMS 6.0 / R2

Document last saved:

Introduction

This technical note describes the web services requirements, how to configure and create your own web services in EPiServer CMS.

Table of Contents

Web Services in EPiServer CMS

The EPiServer CMS sample site includes the following web services ready for use.

  • PageStoreService.asmx. This is a powerful web service that contains methods to retrieve, add, delete and search for information from the EPiServer CMS site.
  • DataFactoryService.asmx. This is an EPiServer 4-compatible version of PageStoreService. Use this when interoperating with an EPiServer CMS 4 site.
  • PageMirroringService.asmx. This is used primarily when mirroring content in EPiServer CMS.
  • ContentChannelService.asmx. This is used when importing content via content channels.

Note The implementation of these services is compiled into episerver.dll. Do not include the .asmx files in your Visual Studio project as you might accidentally create new code-behind files for the services. Click No if Visual Studio asks to create code-behind files for the existing .asmx files. By creating your own web services, you can extend the available functionality of EPiServer CMS and your site. If you place your own services inside the WebServices directory, they will be secured like the built-in EPiServer CMS Web services.

Web Services Requirements

EPiServer CMS is installed, by default, with forms authentication. Web service clients cannot communicate with a web service that uses forms authentication, as the authentication occurs through an HTML user interface meant for visitors on the website. You must use Integrated Windows authentication or follow the steps in Configure EPiServer CMS to Enable Basic Authentication to emulate Basic authentication if you want to use both forms authentication and web services on the same site.

The standard express installation of EPiServer CMS contains a directory called Web Services; the full path is C:\Program Files\EPiServer\CMS\<version number>\Application\WebServices. This directory is protected by default in the web.config file like this:

  <location path="WebServices">
    <!--
      Configure the EPiServer.Security.BasicAuthentication module to send a basic authentication challenge
      instead of a redirect to the forms login page. For this to take effect the EPiServer.Security.BasicAuthentication
      module must be added to the list of http modules.
    -->
    <episerver.basicAuthentication sendBasicChallenge="true" basicRealm=""/>
    <system.web>
      <httpRuntime maxRequestLength="1000000" />
      <authorization>
        <allow roles="WebServices,Administrators" />
        <deny users="*" />
      </authorization>
    </system.web>
  </location>

It is recommended to use a dedicated user for authenticating web service clients, like the "WebServices" user shown above. When using forms authentication on the website, the section shown above will instruct ASP.NET to redirect all requests for .NET-handled files (.aspx, .asmx etc.) to the login form. When you are writing a client program to communicate with any of the existing web services (or any new ones you write) in the /WebServices directory, you do not want the program to be redirected to a page other than the Web service .asmx page. Your client program will not know how to authenticate using the returned HTML, and it will typically throw an exception.

There is a workaround for this in EPiServer CMS if you want to keep forms authentication and still want to expose the web services.

Configure EPiServer CMS to Enable Basic Authentication

Web services cannot authenticate against a forms-authenticated site, because the forms authentication login window requires user interaction. This chapter describes how to configure and set up EPiServer CMS to enable basic authentication, normally only supported when using Windows authentication, on parts of the website.

Note the configuration examples below are for IIS6, for IIS7 examples see the technical note Changes between IIS6 and IIS7.

Step 1: Activate the BasicAuthentication module

The BasicAuthentication http module will translate basic authentication requests on-the-fly to forms-authenticated cookies. Make sure that web.config has the BasicAuthentication filter defined under the httpModules section.

<httpModules>
    <add 
        name="BasicAuthentication" 
        type="EPiServer.Security.BasicAuthentication, EPiServer" /> 

Step 2: Make the BasicAuthentication module send authentication challenge

Configure the EPiServer BasicAuthentication module to send an authentication challenge for the WebServices folder by adding the following configuration to the WebServices location section.

<location path="WebServices">
     <episerver.basicAuthentication sendBasicChallenge="true" basicRealm="" />

Step 3a: Authenticating with Windows accounts

If you’re using a windows account for authentication you have to make sure that the web service account is allowed access in the WebServices folder.

<location path="WebServices">
    <system.web>
        <authorization>
            <allow users="Administrators, WebServices" />
            <deny users="*" />
        </authorization>
    </system.web>
</location>

Step 3b: Authenticating using SqlServer membership accounts

  1. Add a web service user group. Add a group called WebServices to the SQL Server membership provider from EPiServer CMS admin mode.
  2. Configure the WebServices group. To give the WebServices group permission to access the WebServices folder in a default CMS installation, configure the appropriate section of web.config.
    Go to admin mode > Config tab > Permissions for Functions to add your web service user to the list of web service users (to allow the user to act as a web service user).
  3. Add a web service user. Add a new user to the SqlServer memberhip provider and make the user a member of the WebServices group.

Step 4: Disable integrated authentication in IIS

Ensure that the integrated and basic authentication is disabled in IIS.

Step 5: Test the setup

  1. Open a web browser and enter the URL to a web service on your website, for example: http://localhost/WebServices/PageStoreService.asmx. You will receive a standard Windows login pop-up window.
  2. Enter the WebServiceUser account information. If everything is working, you should see the Web Service definition page

Troubleshooting

I Get a Forms Login Prompt, After the Windows Login Prompt

Verify that the user account used for authentication has access to the webservices folder.

Creating Your Own Web Services

If you create your own Web services, place them in the /WebServices folder to have the same security settings as the built-in Web services. This is especially important, if you need to use forms authentication on your site. All the information you can access through the EPiServer API can also be exposed through Web services.

Note If you access an EPiServer Web service using .NET, which has been protected by the BasicAuthentication HttpModule, you need to set PreAuthenticate = true for the .NET Web service proxy code to authenticate each request. 

Creating a Utility Service

The following Web service makes all EPiServer configuration settings available for external clients.

Note This also exposes the connectionstring, usernames and passwords.

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Web;
using System.Web.Services;
using System.Xml;
using System.Text;
using System.IO;
using EPiServer;
using EPiServer.Core;

namespace development.
{
    /// <summary>
    /// Utility members for EPiServer
    /// </summary>
    [WebService(Namespace=http://episerver.com/episerversample/webservices/,
                Description="Utility functions for EPiServer, giving you information about the site.")]
    public class EPiServerUtil : System.Web.Services.
    { 

       [WebMethod(Description="Returns the servers time according to DateTime.Now()")]
        public DateTime ServerTime()
        {
            return DateTime.Now;
        }   

        [WebMethod(Description="Returns all configuration settings for this site as XML.")]
        public string ConfigurationXml()
        {
            System.Collections.Specialized.NameValueCollection oSettings;

            StringBuilder oBuilder = new StringBuilder();
            StringWriter oTextWriter = new StringWriter(oBuilder);
            XmlTextWriter writer = new XmlTextWriter(oTextWriter); 
 
           // Build the XML
            writer.WriteStartDocument();
            writer.WriteStartElement("episerverconfig");
            writer.WriteAttributeString("version", Global.EPConfig.Version );
            writer.WriteStartElement("values");
 
            oSettings = Global.EPConfig.ConfigFile.AllAppSettings;

            for (int i = 0; i < oSettings.Count; i++)
            {
                writer.WriteStartElement("value");
                string[] keyvalue = oSettings.GetValues(i);
                writer.WriteElementString("key", oSettings.Keys[i]);
                writer.WriteElementString("value", string.Join(",", keyvalue));
                writer.WriteEndElement();
            }
            writer.WriteEndElement();
            writer.WriteEndElement();
            writer.WriteEndDocument();

            writer.Flush();
            writer.Close();
            oTextWriter.Close();

            return oBuilder.ToString();
        }     
        public EPiServerUtil()
        {
            //CODEGEN: This call is required by the ASP.NET Web Services Designer
            InitializeComponent();
        } 
  
        //Required by the Web Services Designer 
        private IContainer components = null;
        private void InitializeComponent()
        {
        }

        protected override void Dispose( bool disposing )
        {
            if(disposing && components != null)
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }
    }
}

Consuming the Web Service

  1. Create a new C# Console project in Visual Studio.
  2. Add a Web Reference to the newly created Web Service.
  3. When using .NET 4, the classes are generated using the WCF way. You need to change the username, password and domain. Use the following code examples for the implementation:
    The username and password can still be changed via code but through the .ClientCredentials property of the SOAP client class.
    var client = new MyServiceReference.MyServiceSoapClient(); client.ClientCredentials.UserName.UserName = "user"; client.ClientCredentials.UserName.Password = "password";
  4. Change the security mode from the default settings to the following when adding the web reference in .config file:
    <security mode="TransportCredentialOnly"> <transport clientCredentialType="Basic" /> </security>

.NET 2

Use the following code for the implementation (remember to change the username, password and domain):

using System;
using System.Text;
using System.Xml;
using System.Net;

// Change this to the namespace of your webservice
using ConsoleTest.localhost;

namespace ConsoleTest
{
    class ConsoleTest
    {
        [STAThread]
        static void Main(string[] args)
        {
            StringBuilder allSettings = new StringBuilder();
            EPiServerUtil wsUtil = new EPiServerUtil();
            wsUtil.Credentials = new NetworkCredential("john", "doe", "DOMAIN");
            wsUtil.PreAuthenticate = true;
            string settingsXml = wsUtil.ConfigurationXml();
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.LoadXml(settingsXml);
            XmlNodeList nodes = xmlDoc.SelectNodes("/episerverconfig/values/value");
            foreach (XmlNode node in nodes)
            {
                allSettings.AppendFormat("{0} = {1}\r\n",
                node.SelectSingleNode("key").InnerText,
                node.SelectSingleNode("value").InnerText);

            }
            Console.Out.Write(allSettings.ToString());
        }
    }
}

Communication with .NET Soap Client

When communicating with EPiServer CMS using a .NET soap client, set the property SoapHttpClientProtocol.PreAuthenticate to true to make sure that the username and password are sent to the server at every request, instead of using the default behavior that relies on connection keep-alive and access-denied round-trips.

The main reason is that if the client and server are using connection keep-alive without storing cookies, the BasicAuthentication filter may not be able to capture subsequent requests that reuse a previously authenticated connection.