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
- Web Services Requirements
- Configure EPiServer CMS to Enable Basic Authentication
» Step 1: Activate the BasicAuthentication module
» Step 2: Make the Basic Authentication module send authentication challenge
» Step 3a: Authenticating with Windows accounts
» Step 3b: Authenticating using SqlServer membership accounts
» Step 4: Disable integrated authentication in IIS
» Step 5: Test the Setup - Troubleshooting
- Creating Your Own Web Services
- Creating a Utility Service
- Consuming the Web Service
- Communication with .NET Soap Client
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
- 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: Disable integrated authentication in IIS
Ensure that the integrated and basic authentication is disabled in IIS.
Step 5: Test the setup
- 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 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
- 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.
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:
<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.