You can use a message inspector, which is called for every request coming to the service. The code below shows one implementation of such an inspector.
public class StackOverflow_25380450
{
[ServiceContract]
public class Service
{
[WebGet]
public int Add(int x, int y)
{
return x + y;
}
}
public class MyInspector : IDispatchMessageInspector, IEndpointBehavior
{
public const string LicenseHeaderName = "X-License";
public const string ExpectedLicense = "abcdef";
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
HttpRequestMessageProperty reqProp = (HttpRequestMessageProperty)request.Properties[HttpRequestMessageProperty.Name];
var license = reqProp.Headers[LicenseHeaderName];
if (license != ExpectedLicense)
{
throw new WebFaultException<string>("License required", HttpStatusCode.Forbidden);
}
return null;
}
public void BeforeSendReply(ref Message reply, object correlationState)
{
}
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
endpointDispatcher.DispatchRuntime.MessageInspectors.Add(this);
}
public void Validate(ServiceEndpoint endpoint)
{
}
}
public static string SendGet(string uri, Dictionary<string, string> headers)
{
string responseBody = null;
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(uri);
req.Method = "GET";
if (headers != null)
{
foreach (string headerName in headers.Keys)
{
switch (headerName)
{
case "Accept":
req.Accept = headers[headerName];
break;
default:
req.Headers[headerName] = headers[headerName];
break;
}
}
}
HttpWebResponse resp;
try
{
resp = (HttpWebResponse)req.GetResponse();
}
catch (WebException e)
{
resp = (HttpWebResponse)e.Response;
}
if (resp == null)
{
responseBody = null;
Console.WriteLine("Response is null");
}
else
{
Console.WriteLine("HTTP/{0} {1} {2}", resp.ProtocolVersion, (int)resp.StatusCode, resp.StatusDescription);
foreach (string headerName in resp.Headers.AllKeys)
{
Console.WriteLine("{0}: {1}", headerName, resp.Headers[headerName]);
}
Console.WriteLine();
Stream respStream = resp.GetResponseStream();
if (respStream != null)
{
responseBody = new StreamReader(respStream).ReadToEnd();
Console.WriteLine(responseBody);
}
else
{
Console.WriteLine("HttpWebResponse.GetResponseStream returned null");
}
}
Console.WriteLine();
Console.WriteLine(" *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* ");
Console.WriteLine();
return responseBody;
}
public static void Test()
{
string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
var endpoint = host.AddServiceEndpoint(typeof(Service), new WebHttpBinding(), "");
endpoint.Behaviors.Add(new WebHttpBehavior { AutomaticFormatSelectionEnabled = true });
endpoint.Behaviors.Add(new MyInspector());
host.Open();
Console.WriteLine("Host opened");
Console.WriteLine("No license:");
Dictionary<string, string> headers = new Dictionary<string, string>
{
{ "Accept", "application/json" }
};
SendGet(baseAddress + "/Add?x=6&y=8", headers);
Console.WriteLine("Incorrect license:");
headers.Add(MyInspector.LicenseHeaderName, "incorrect");
SendGet(baseAddress + "/Add?x=6&y=8", headers);
headers[MyInspector.LicenseHeaderName] = MyInspector.ExpectedLicense;
SendGet(baseAddress + "/Add?x=6&y=8", headers);
Console.Write("Press ENTER to close the host");
Console.ReadLine();
host.Close();
}
}
You can find more information about inspectors in general at http://blogs.msdn.com/b/carlosfigueira/archive/2011/04/19/wcf-extensibility-message-inspectors.aspx.