I'm trying to connect to a C#/WCF server endpoint constructed as follows:
Uri baseAddress = new Uri(net.tcp://localhost:8000/MyService.svc);
m_svcHost = new ServiceHost(myService, baseAddress);
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpsGetEnabled = false;
m_svcHost.Description.Behaviors.Add(smb);
m_svcHost.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = UserNamePasswordValidationMode.Custom;
m_svcHost.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = new NameValidator();
m_svcHost.Credentials.ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
m_svcHost.Credentials.ServiceCertificate.Certificate = Misc.ImportCertificate(System.Reflection.Assembly.GetExecutingAssembly(), "Service.Certificates.RCA.pfx");
m_svcHost.Credentials.ClientCertificate.Certificate = Misc.ImportCertificate(System.Reflection.Assembly.GetExecutingAssembly(), "Service.Certificates.Signed.cer");
NetTcpBinding netTcpBind = new NetTcpBinding(SecurityMode.TransportWithMessageCredential);
netTcpBind.Security.Transport.ClientCredentialType = TcpClientCredentialType.Windows;
netTcpBind.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
m_svcHost.AddServiceEndpoint(typeof(IMyService), netTcpBind, baseAddress);
My client is written in C++/WWS:
// declare and initialize a username credential
WS_STRING_USERNAME_CREDENTIAL usernameCredential = {}; // zero out the struct
static const WS_STRING userName = WS_STRING_VALUE(L"username");
static const WS_STRING passWord = WS_STRING_VALUE(L"password");
usernameCredential.credential.credentialType = WS_STRING_USERNAME_CREDENTIAL_TYPE; // set the credential type
usernameCredential.username = userName;
usernameCredential.password = passWord;
// declare and initialize a username message security binding
WS_USERNAME_MESSAGE_SECURITY_BINDING usernameBinding = {};
usernameBinding.binding.bindingType = WS_USERNAME_MESSAGE_SECURITY_BINDING_TYPE;
usernameBinding.bindingUsage = WS_SUPPORTING_MESSAGE_SECURITY_USAGE;
usernameBinding.clientCredential = &usernameCredential.credential;
WS_SECURITY_BINDING* securityBindings[1] = { &usernameBinding.binding };
WS_SECURITY_DESCRIPTION securityDescription = {};
securityDescription.securityBindings = securityBindings;
securityDescription.securityBindingCount = WsCountOf(securityBindings);
WS_CHANNEL* channel = nullptr;
WS_ERROR* error = nullptr;
HRESULT hr = WsCreateError(
nullptr,
0,
&error);
hr = WsCreateChannel(
WS_CHANNEL_TYPE_DUPLEX_SESSION,
WS_TCP_CHANNEL_BINDING,
nullptr,
0,
&securityDescription,
&channel,
error);
if (FAILED(hr))
{
wprintf(L"Failure: errorCode=0x%lx\n", hr);
}
WS_ENDPOINT_ADDRESS address;
address.url.chars = L"net.tcp://localhost:8000/MyService.svc";
address.url.length = (ULONG)::wcslen(address.url.chars);
address.headers = NULL;
address.extensions = NULL;
address.identity = NULL;
// Open channel to address
hr = WsOpenChannel(
channel,
&address,
nullptr,
error);
if (FAILED(hr))
{
wprintf(L"Failure: errorCode=0x%lx\n", hr);
}
I keep getting the following output:
Failure: errorCode=0x80070057
The channel object specified is invalid.
The specified message security binding can only be used with an additional binding (such as the SSL binding) for message protection.
My WCF client can connect and use this WCF service but another application needs to be able to connect to it using only native C++ which is my reason for using WWS even though I am very unfamiliar with it.
What changes do I need to make to my client in order to be able to create this channel in WWS?
User contributions licensed under CC BY-SA 3.0