views:

508

answers:

2

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?

+1  A: 

You have some:

        throw new NotImplementedException(); 

in your code. These could be the exceptions that are being thrown. Try removing these and see if you get the same error.

Shiraz Bhaiji
I don't really think that this is the problem, I didn't implement those method on purpose, simply because I don't make use of'em.
exalted
Are you sure that the framework does not run these methods
Shiraz Bhaiji
Yeah, pretty sure. Also because this guy made it work somehow...
exalted
A: 

Shiraz Bhaiji is right. The framework does call those methods that you are throwing not implemented exceptions. Remove that.

AbdElRaheim
I'm terribly sorry, but I've already changed my direction on WCF security issue, therefore I can't verify that.For the records: after all that I've tried, http://www.codeproject.com/KB/WCF/wcfcertificates.aspx did the trick for me.
exalted