WCF security via message headers

Posted by exalted on Stack Overflow See other posts from Stack Overflow or by exalted
Published on 2010-04-07T14:09:57Z Indexed on 2010/04/07 14:13 UTC
Read the original article Hit count: 878

Filed under:
|
|

I'm trying to implement "some sort of" server-client & zero-config security for some WCF service.

The best (as well as easiest to me) solution that I found on www is the one described at http://www.dotnetjack.com/post/Automate-passing-valuable-information-in-WCF-headers.aspx (client-side) and http://www.dotnetjack.com/post/Processing-custom-WCF-header-values-at-server-side.aspx (corrisponding server-side).

Below is my implementation for RequestAuth (descibed in the first link above):

using System;
using System.Diagnostics;
using System.ServiceModel;
using System.ServiceModel.Configuration;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Description;
using System.ServiceModel.Channels;

namespace AuthLibrary
{
    /// <summary>
    /// Ref: http://www.dotnetjack.com/post/Automate-passing-valuable-information-in-WCF-headers.aspx
    /// </summary>
    public class RequestAuth : BehaviorExtensionElement, IClientMessageInspector, IEndpointBehavior
    {
        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
        private string headerName = "AuthKey";

        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
        private string headerNamespace = "http://some.url";

        public override Type BehaviorType
        {
            get { return typeof(RequestAuth); }
        }

        protected override object CreateBehavior()
        {
            return new RequestAuth();
        }

        #region IClientMessageInspector Members

        // Keeping in mind that I am SENDING something to the server,
        // I only need to implement the BeforeSendRequest method

        public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
        {
            throw new NotImplementedException();
        }

        public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel)
        {
            MessageHeader<string> header = new MessageHeader<string>();
            header.Actor = "Anyone";
            header.Content = "TopSecretKey";

            //Creating an untyped header to add to the WCF context 
            MessageHeader unTypedHeader = header.GetUntypedHeader(headerName, headerNamespace);

            //Add the header to the current request 
            request.Headers.Add(unTypedHeader);

            return null;
        }

        #endregion

        #region IEndpointBehavior Members

        public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
        {
            throw new NotImplementedException();
        }

        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
            clientRuntime.MessageInspectors.Add(this);
        }

        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        {
            throw new NotImplementedException();
        }

        public void Validate(ServiceEndpoint endpoint)
        {
            throw new NotImplementedException();
        }

        #endregion
    }
}

So first I put this code in my client WinForms application, but then I had problems signing it, because I had to sign also all third-party references eventhough http://msdn.microsoft.com/en-us/library/h4fa028b(v=VS.80).aspx at section "What Should Not Be Strong-Named" states:

In general, you should avoid strong-naming application EXE assemblies. A strongly named application or component cannot reference a weak-named component, so strong-naming an EXE prevents the EXE from referencing weak-named DLLs that are deployed with the application.

For this reason, the Visual Studio project system does not strong-name application EXEs. Instead, it strong-names the Application manifest, which internally points to the weak-named application EXE.

I expected VS to avoid this problem, but I had no luck there, it complained about all the unsigned references, so I created a separate "WCF Service Library" project inside my solution containing only code above and signed that one.

At this point entire solution compiled just okay.

And here's my problem:

When I fired up "WCF Service Configuration Editor" I was able to add new behavior element extension (say "AuthExtension"), but then when I tried to add that extension to my end point behavior it gives me:

Exception has been thrown by the target of an invocation.

So I'm stuck here.

Any ideas?

© Stack Overflow or respective owner

Related posts about wcf

Related posts about security