Data FAQ

How can I validate users before a page or media file is being served?

I would like to create extranet functionality on my site and for this I need to validate page and media requests, redirect users not authenticated and control what gets publically cached.

Answer:

Composite C1 allow you to build a RenderingResponseHandler plug-in. It enables developers to intercept page and media requests and control if the request should be accepted or redirected and if the rendered page is allowed to be publicly cached.

To create a RenderingResponseHandler plug-in:

  1. In Visual Studio, create a new "Class Library" project (or use an existing project if you have one).
  2. Add references to the following assemblies (Browse and located on your web site):
    • /bin/Composite.dll
    • /bin/Microsoft.Practices.EnterpriseLibrary.Common.dll
  3. In each assembly reference's properties, set Copy Local to 'False'.
  4. Add a reference to System.Configuration (.NET)
  5. Create a new class for your plug-in (see the source code example below).
  6. Compile the project and copy the DLL to the website /bin folder.

Sample source code:

using System;

using Composite.Data;
using Composite.Data.Types;
using Composite.Core.Logging;
using Composite.Core.WebClient.Renderings;
using Composite.Core.WebClient.Renderings.Plugins.RenderingResponseHandler;

using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;


namespace RenderingResponseHandlerSample
{
    [ConfigurationElementType(typeof(NonConfigurableRenderingResponseHandler))]
    public class RenderingResponseHandlerPluginSample : IDataRenderingResponseHandler
    {
        // Have the TCP logger running to see the string being logged - see Composite.Tools.TcpCustomTraceListener
        // This sample will redirect requests for pages and media containing the word 'secret' in their title / path.
        public RenderingResponseHandlerResult GetDataResponseHandling(DataEntityToken requestedItemEntityToken)
        {
            IData requestedData = requestedItemEntityToken.Data;

            bool redirect = false;

            if (requestedData is IPage)
            {
                IPage requestedPage = (IPage)requestedData;
                LoggingService.LogVerbose("Sample", string.Format("Request for page '{0}'.", requestedPage.Title));

                if (requestedPage.Title.ToLower().Contains("secret"))
                {
                    redirect = true;
                }
            }
            else if (requestedData is IMediaFile)
            {
                IMediaFile requestedMediaFile = (IMediaFile)requestedData;
                LoggingService.LogVerbose("Sample", string.Format("Request for media file '{0}'.", requestedMediaFile.CompositePath));

                if (requestedMediaFile.CompositePath.ToLower().Contains("secret"))
                {
                    redirect = true;
                }
            }

            if (redirect)
            {
                return new RenderingResponseHandlerResult { 
                    PreventPublicCaching = true,
                    RedirectRequesterTo = new Uri("http://docs.composite.net/")
                };
            }
            else
            {
                return new RenderingResponseHandlerResult { 
                    PreventPublicCaching = false 
                };
            }
        }
    }
}

Download the source

To register a RenderingResponseHandler plug-in:

  1. Edit the file /App_Data/Composite/Composite.config.
  2. Locate the element <RenderingResponseHandlerPlugins />.
  3. Add a new element inside the <RenderingResponseHandlerPlugins /> element:

    <add name="Sample" type="TypeName, AssemblyName"/>

    changing 'Sample' to a name relevant to your project and 'TypeName, AssemblyName' to the fully qualified class name of your plug-in class.
  4. Restart the C1 site (recycle app pool)

Sample configuration:

<Composite.Core.WebClient.Renderings.Plugins.RenderingResponseHandlerConfiguration>
  <RenderingResponseHandlerPlugins>
    <add name="Sample" type="RenderingResponseHandlerSample.RenderingResponseHandlerPluginSample, RenderingResponseHandlerSample" />
  </RenderingResponseHandlerPlugins>
</Composite.Core.WebClient.Renderings.Plugins.RenderingResponseHandlerConfiguration>

The sample code will emit the titles / paths of media files being requested - you can see these log elements if you use the verbose C1 Log Viewer.