0
  • I have a client for an older service that I am trying to migrate to WCF.

  • The service is hand written in assembler on *nix.

  • The client is written in WSE3 in C++.

  • The WSDL, of course does not supply security specs, but I have an interface doc.

    • The service supplies us with one certificate for the server with only a public key. The WSE3 client is using that one certificate to sign the security header and the message body as well as encrypting them both.
    • WCF is balking hard at this and wants a private key. The security header is based on WS-Security 1.0.
  • I need a UsernameToken.

  • I have tried multiple different approaches. The app.config with BasicHTTPBinding which is what Service import left me with and WSHttpBinding.

  • Because this is a COM DLL that we deploy to clients, I moved away from the config route and started directly coding the binding.

  • There are some good posts and even some answers here in SO from Yaron Naveh that I have been working with that use AsymetricSecurityBinding that feels like the right approach, but eventually I end up with a 'The private key is not present in the X.509 certificate.' message.

This is my current approach, modified for presentation:

CustomBinding b = new CustomBinding();

var profileEnum = MessageSecurityVersion.WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10;

var sec = (AsymmetricSecurityBindingElement)SecurityBindingElement.CreateMutualCertificateBindingElement( profileEnum );

sec.EndpointSupportingTokenParameters.Signed.Add( new UserNameSecurityTokenParameters() );
sec.MessageSecurityVersion = MessageSecurityVersion.WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10;
sec.IncludeTimestamp       = false;
sec.MessageProtectionOrder = MessageProtectionOrder.EncryptBeforeSign;

b.Elements.Add( sec );
b.Elements.Add( new TextMessageEncodingBindingElement( MessageVersion.Soap11, Encoding.UTF8 ) );
b.Elements.Add( new HttpsTransportBindingElement() );

EndpointAddress addr = new EndpointAddress(
    new Uri(URL),
    new DnsEndpointIdentity( "yada.yada.com" ),
    new AddressHeaderCollection()
);

client = new AWebService.SomeServiceClient( b, addr );

String credName = "my.hot.site.com";
client.ClientCredentials.ClientCertificate.SetCertificate(
    StoreLocation.LocalMachine,
    StoreName.Root,
    X509FindType.FindBySubjectName,
    credName
);
client.ClientCredentials.ServiceCertificate.SetDefaultCertificate(
    StoreLocation.LocalMachine,
    StoreName.Root,
    X509FindType.FindBySubjectName,
    credName
);

client.Endpoint.Contract.ProtectionLevel   = ProtectionLevel.Sign;
ServicePointManager.SecurityProtocol       = SecurityProtocolType.Tls12;
client.ClientCredentials.UserName.UserName = "samuser";
client.ClientCredentials.UserName.Password = "iampass";
client.Endpoint.EndpointBehaviors.Add( new ClientMessageInspectorBehavior() );

response = client.call(requestData);

What I need is

  1. A setup that will get me a WSSE Security header with a UserNameToken and
  2. A way to sign and encrypt the outgoing request as well as check the response signature.
Dai
  • 141,631
  • 28
  • 261
  • 374
  • 1
    "I am trying to migrate to WCF" - why on earth are you wanting to migrate **to** WCF? I've been working to migrate projects away from WCF for most of the past decade now. – Dai Dec 15 '21 at 15:19
  • "The service is hand written in assembler on *nix." - **run** – Dai Dec 15 '21 at 15:28
  • I had to check you weren't pulling a joke on us with `WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10` - but no, [_it's real_](https://learn.microsoft.com/en-us/dotnet/api/system.servicemodel.messagesecurityversion.wssecurity10wstrust13wssecureconversation13wssecuritypolicy12basicsecurityprofile10) - I'm convinced that Microsoft hired a bunch of "Enterprise" Java types in the early 2000s and WCF was the end-result. – Dai Dec 15 '21 at 15:29
  • The reason to migrate off of WSE3 is security and ciphers. WSE3 only supports SHA-1. – Allen McDonald Dec 15 '21 at 16:17
  • Hope these links can help you:1.A setup that will get me a WSSE Security header with a UserNameToken:https://stackoverflow.com/questions/56017114/how-to-generate-usernametoken-for-ws-security 2.A way to sign and encrypt the outgoing request as well as check the response signature:https://learn.microsoft.com/en-us/dotnet/framework/wcf/extending/how-to-create-a-custom-client-identity-verifier – Lan Huang Dec 16 '21 at 07:05

0 Answers0