Search code examples
wcfws-security

Wcf WS-Security server


i have created service with such binding configuration:

<bindings>
  <customBinding>
    <binding name="DefaultBinding">
      <textMessageEncoding messageVersion="Soap12" />
      <httpTransport />
    </binding>
  </customBinding>
</bindings>

And when my service receives message starting like this:

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
  <s:Header>
    <Security s:mustUnderstand="1" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
      <UsernameToken>
        <Username>
        </Username>
        <Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">...</Password>
        <Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">KWVa4abCrEemOMT55VEZkgIAAAAAAA==</Nonce>
        <Created xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2013-08-28T13:29:05.966Z</Created>
      </UsernameToken>
    </Security>
    ...

It produces error:

The header 'Security' from the namespace 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd' was not understood ...

I also tried:

<wsHttpBinding>
    <binding name="DefaultBinding">
      <security  mode="Message" />
    </binding>
</wsHttpBinding>

How i can process this header or ignore it ?


Update

As i understood i need username over insecure transport, so i tried:

<customBinding>
    <binding
        name="DefaultBinding">
      <textMessageEncoding messageVersion="Soap12" />
      <security authenticationMode="UserNameOverTransport" allowInsecureTransport="True">
      </security>
      <httpTransport>

      </httpTransport>
    </binding>
</customBinding>

I also tried CUB:

<bindings>
  <clearUsernameBinding>
    <binding name="myClearUsernameBinding" messageVersion="Soap12">
    </binding>
  </clearUsernameBinding>
</bindings>

Both ends with error on client: An error occurred when verifying security for message. But it works with test CUB's client. What could be wrong ?

CUB's envelope's header.

Test client's header.


Solution

  • Solution was simple:

    1. Create service behavior
    2. Create dispatch message inspector
    3. Add created service behavior to server

    And then just parse or just delete unused "mustUnderstand" headers.

    Step 1:

    public class WSSecurityBehavior : IServiceBehavior {
        public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) {
        }
    
        public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase,
            Collection<ServiceEndpoint> endpoints,
            BindingParameterCollection bindingParameters) {
        }
    
        public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) {
            var endpoints = serviceHostBase
                .ChannelDispatchers
                .Cast<ChannelDispatcher>()
                .SelectMany(dispatcher => dispatcher.Endpoints);
    
            foreach (var endpoint in endpoints)
                endpoint.DispatchRuntime.MessageInspectors.Add(new WSSecurityInspector());
        }
    }
    

    Step 2:

    public class WSSecurityInspector : IDispatchMessageInspector {
        public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) {
            var headerPosition = request.Headers.FindHeader("Security",
                "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
    
            if (headerPosition > -1)
                request.Headers.RemoveAt(headerPosition);
    
            return null;
        }
    
        public void BeforeSendReply(ref Message reply, object correlationState) {
        }
    }
    

    Step 3:

    Host.Description.Behaviors.Add(new WSSecurityBehavior());