Configuring Web Services Authentication
Table of Contents
- Introduction
- Prerequisites
- Configuring EPiServer CMS to Enable Basic Authentication
- Troubleshooting
- Creating Your Own Web Services
- Creating a Utility Service
- Consuming the Web Service
- Communicating with the .NET SOAP Client
Introduction
Web Services are APIs that can be accessed over a network and executed on a remote system hosting the requested services. Web services is the most widely used non-EPiServer specific integration method. The integration is made at the business layer and a web service will provide functionality or data to an EPiServer CMS site. It will still be necessary though to implement the user interface on top of the web service.
The EPiServer CMS sample site installation 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-compatible version of PageStoreService. Use this when interoperating with an EPiServer CMS site.
- ContentChannelService.asmx. This is used when importing content via content channels.
Prerequisites
EPiServer CMS is installed with forms authentication by default. 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 the section Configuring EPiServer CMS to Enable Basic Authentication below, 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 as follows:
<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>
Configuring 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 section 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.
Step 1: Activating the BasicAuthentication Module
The BasicAuthentication http module will translate basic authentication requests on-the-fly to forms-authenticated cookies. Make sure to define the BasicAuthentication filter under the <system.webserver><modules> section section in web.config as follows:
<system.webServer>
<modules ...>
<add name="BasicAuthentication" type="EPiServer.Security.BasicAuthentication, EPiServer" />
<!-- Other modules -->
</modules>
</system.webServer>
Step 2: Making the BasicAuthentication Module to 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 in web.config:
<location path="WebServices">
<episerver.basicAuthentication sendBasicChallenge="true" basicRealm="" />
Step 3a: Authenticating with Windows Accounts
If you are using a windows account for authentication you have to make sure that the web service account is allowed access to the WebServices folder.
<location path="WebServices">
<system.web>
<authorization>
<allow roles="Administrators, WebServices" />
<deny users="*" />
</authorization>
</system.web>
</location>
Step 3b: Authenticating Using SQL Server Membership Accounts
- Add a web service user group. Add a group called WebServices to the SQL Server membership provider from EPiServer CMS admin mode.
- 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). - 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: Disabling Integrated Authentication in IIS
Ensure that the integrated and basic authentication is disabled in IIS.
Step 5: Testing the Configuration
- 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.
- Enter the WebServiceUser account information. If everything is working, you will 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.
I get an unauthorized message when trying to logon using the web service user I have just created
Verify that you have made all necessary configuration settings for authentication under Step 3.
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.
Creating a Utility Service
The following web service makes all EPiServer CMS configuration settings available for external clients:
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=<a href="http://episerver.com/episerversample/webservices/">http://episerver.com/episerversample/webservices/</a>,
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
- Create a new C# Console project in Visual Studio.
- Add a web reference to the newly created web service.
- 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.
C#var client = new MyServiceReference.MyServiceSoapClient(); client.ClientCredentials.UserName.UserName = "user"; client.ClientCredentials.UserName.Password = "password";
- Change the security mode from the default settings to the following when adding the
web reference in .config file:
C#<security mode="TransportCredentialOnly"> <transport clientCredentialType="Basic" /> </security>
Communicating with the .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.
Last updated: Mar 25, 2013