Opticon Stockholm is on Tuesday September 10th, hope to see you there!
Opticon Stockholm is on Tuesday September 10th, hope to see you there!
Product version: |
EPiServer CMS 5 R2 SP1 |
---|---|
Document version: |
1.1 |
Document last saved: |
31-03-2009 |
This technical note describes the Web services requirements, how to configure and create your own Web services in EPiServer CMS 5.
The EPiServer CMS 5 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 5 site.
DataFactoryService.asmx
This is an EPiServer 4-compatible version of PageStoreService. Use this when interoperating with an EPiServer 4 site.
PageMirroringService.asmx
This is used primarily when mirroring content in EPiServer CMS 5.
ContentChannelService.asmx
This is used when importing content with the new Content Channel feature. See separate technical note for details.
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 and your site. If you place your own services inside the WebServices directory, they will be secured like the built-in EPiServer CMS 5 Web services.
EPiServer CMS 5 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 Web site. You must use Integrated Windows authentication or follow the steps in Configure EPiServer CMS 5 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 5 R2 contains a directory called Web Services; the full path is C:\Program Files\EPiServer\CMS\5.2.375.131\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 Web site, 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 5 if you want to keep forms authentication and still want to expose the Web services.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 to enable basic authentication, normally only supported when using Windows authentication, on parts of the Web site.
Note the configuration examples below are for IIS6, for IIS7 examples see the technical note Changes between IIS6 and IIS7.
Edit the Web configuration file, web.config, in the EPiServer root directory. Make sure that the Web service account is allowed access in the WebServices folder.
<location path="WebServices">
<system.web>
<authorization>
<allow users="DOMAIN\MyWebServiceUser" />
<deny users="*" />
</authorization>
</system.web>
</location>
Replace DOMAIN with the name of the domain or local machine where the user account was created.
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" />
As part of the EPiServer CMS 5 R2 release the WebServices folder was moved to Program Files\EPiServer\CMS\5.2.375.133\Application\WebServices . In order to add authentification on the WebServices folder complete the following steps:
Make sure that the WebService user has access to log on to the server. Normally you have to either make this user a member of the Users group, or enable the local policy “Log on locally”. Also check that the user has NTFS access to the WebServices folder. Most often you have to restart Internet Information Services after changing security settings in Windows such as policy or NTFS rights.
Enter the username and password in the forms authentication prompt. If you get through, verify that the BasicAuthentication filter is installed correctly.
If everything apart from the forms login to the WebServices folder works, verify the web.config settings. For example, if you are logging on with COMPUTER\MyWebServiceUser, verify that the identical name was set in web.config. Skipping domain or adding the wrong domain could be the problem. Most often you have to restart Internet Information Services after changing security settings in Windows, such as policy or NTFS rights.
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.
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);
}
}
}
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());
}
}
}
When communicating with EPiServer CMS 5 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.