Change clientCredentialType to UserName, but using x509 certificate - wcf

I have made a wcf application, and a client. WCF app. have to know what user and password had accessed the service operation. That is what i done:
Server web config:
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="wsHttpEndpointBinding">
<security>
<message clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="Auth">
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceMetadata httpGetEnabled="true"/>
<serviceCredentials>
<clientCertificate>
<authentication certificateValidationMode="PeerTrust"/>
</clientCertificate>
<serviceCertificate findValue="WCfServer"
storeLocation="CurrentUser"
storeName="My"
x509FindType="FindBySubjectName" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="Auth" name="Service">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsHttpEndpointBinding" contract="IService"/>
</service>
</services>
</system.serviceModel>
<system.web>
<compilation debug="true"/>
</system.web>
</configuration>
Client config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text"
textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Message">
<transport clientCredentialType="Windows" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Certificate" negotiateServiceCredential="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="CustomBehavior">
<clientCredentials>
<clientCertificate findValue="WcfClient" x509FindType="FindBySubjectName" storeLocation="CurrentUser" storeName="My" />
<serviceCertificate>
<authentication certificateValidationMode="PeerTrust"/>
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<client>
<endpoint address="http://localhost:30341/WCFAuthTest/Service.svc"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService"
contract="Service.IService" name="WSHttpBinding_IService" behaviorConfiguration="CustomBehavior">
<identity>
<dns value="WcfServer" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
How i generated certificates: http://www.codeproject.com/KB/WCF/9StepsWCF.aspx
Service operation:
public string TestAccess()
{
return OperationContext.Current.ServiceSecurityContext.PrimaryIdentity.Name;
}
Client:
ServiceClient client = new ServiceClient();
client.ClientCredentials.UserName.UserName = "Admin";
client.ClientCredentials.UserName.Password = "123";
Console.WriteLine(client.TestAccess());
Console.ReadLine();
And program must return Admin but it doesn't:
http://img27.imageshack.us/img27/3104/returnz.png
I know that i have to change the clientCredentialType to UserName, but it gaves me an error

If you want to pass user name and password you must set client credential type to UserName. Setting it to certificate is for using client certificates. Here is some how to article.

Related

How to configure service reference to point to Https, with MutualSSL setup?

In my project I recently changed my WCF service to use Https. It is configured to be a mutual ssl setup and the client and server certificates are both installed appropriately. Server side looks fine and even started fine in the browser as shown below.
However, when trying to configure the service reference from the WPF client side (service proxy that was previously added and generated). I get a 403 forbidden error code as shown below. Any idea why?
Here are my configurations.
WCF Server Side Config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5.2" />
<httpRuntime targetFramework="4.5.2" />
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceCredentials>
<serviceCertificate storeLocation="LocalMachine" x509FindType="FindByIssuerName" findValue="QuickFire Root Authority" />
</serviceCredentials>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="PushNotification_SignalR_PoC.WCF.PushNotificationService">
<endpoint binding="wsHttpBinding" bindingConfiguration="MutualSslLargeMessageBinding" contract="PushNotification_SignalR_PoC.WCF.IPushNotificationService" />
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="MutualSslLargeMessageBinding" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
<security mode="Transport">
<transport clientCredentialType="Certificate"></transport>
</security>
</binding>
</wsHttpBinding>
</bindings>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<directoryBrowse enabled="true" />
</system.webServer>
</configuration>
WPF Client Side Config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WsHttpBinding_IPushNotificationService"
closeTimeout="00:01:00" openTimeout="00:01:00"
receiveTimeout="00:30:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647"
maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
<security mode="Transport">
<transport clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="https://localhost:44367/PushNotificationService.svc"
binding="wsHttpBinding" bindingConfiguration="WsHttpBinding_IPushNotificationService"
contract="ServiceProxy.IPushNotificationService" name="WsHttpBinding_IPushNotificationService" />
</client>
<behaviors>
<endpointBehaviors>
<behavior name="MutualSslBehavior">
<clientCredentials>
<clientCertificate storeLocation="CurrentUser" x509FindType="FindBySubjectName" findValue="QuickFire Test Client"/>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
If we want to call the service by adding service reference, we should add the MEX endpoint in the service endpoints on the server side. It could exchange metadata of the service over all platforms.
Like below,
<services>
<service name="PushNotification_SignalR_PoC.WCF.PushNotificationService">
<endpoint binding="wsHttpBinding" bindingConfiguration="MutualSslLargeMessageBinding" contract="PushNotification_SignalR_PoC.WCF.IPushNotificationService" />
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange"></endpoint>
</service>
</services>
For details,
https://learn.microsoft.com/en-us/dotnet/framework/wcf/extending/how-to-configure-a-custom-ws-metadata-exchange-binding
Feel free to let me know if there is anything I can help with.

WCF webservice needs to listen on 2 ports iisexpress. TCP error code 10061

We have a wcf webservice that an external client will be using to provide requests. This webservice (the webservice) calls another wcf service ( the agent) where the business logic is implemented.
The agent also monitors activity in the database and when the requested information is ready (often days later) the agent generates an object containing the requested data. It needs to pass the object to the webservice where the webservice will form XML and post it to the clients webservice.
The webservice implements two different imterfaces, one that the client uses and one that the agent uses.
The trouble is, on the local machine, I am unable to get the agent to connect to the webservice to send the results. Both the webservice and the agent are running on my local machine for debugging purposes. In VisualStudio2012, the webservice project is set up to use IISExpress and defines a specific port to use. Project URL: https://local.someaddress.net:51448/ However, the port the agent uses to try to connect to the webservice is a different port.
The webservice is able to call the agent just fine, but the agent gets a tcp error code 10061 when it tries to call the webservice.
I've already tried "appcmd.exe set app "Default Web Site/" /enabledProtocols:http,net.tcp".
Is it possible to configure IISExpress to have the webservice open both ports? Or is there something obvious I am missing here?
(Since the config files contain links to localhost and stackoverflow doesn't allow that, I have replaced localhost with local.someaddress.net.)
Here are the contents of the webservice's web.config:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" maxRequestLength="52428800"/>
</system.web>
<system.serviceModel>
<client>
<endpoint address="net.tcp://local.someaddress.net:8102/Acord/201307" behaviorConfiguration="NetTcpCertificatesBehavior" binding="netTcpBinding" bindingConfiguration="NetTcpCertificatesBinding" contract="AcordContract.IAcordService201307" name="AcordEndpoint">
<identity>
<certificateReference findValue="7da522dd75f3fca2687837b7b67e117a8700ec62" isChainIncluded="false" storeLocation="LocalMachine" x509FindType="FindByThumbprint" />
</identity>
</endpoint>
</client>
<services>
<service name="AcordWebService.AcordWebService" behaviorConfiguration="Visible">
<endpoint address="" binding="basicHttpsBinding" contract="AcordWebService.IAcordWebService" bindingConfiguration="BasicHttpsBinding">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
<!--binding for clients outside the firewall calling from C# with WCF using certs -->
<endpoint address="net.tcp://local.someaddress.net:8122/AcordWebService/201309" binding="netTcpBinding" bindingConfiguration="NetTcpCertificatesBinding" name="NetTcpCertificatesEndpoint" contract="AcordWSContract.IAcordWSService201309">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="NetTcpCertificatesBehavior">
<clientCredentials>
<clientCertificate findValue="631f5a67a9a70bc78540bb809e73fd1dbd00bbeb" storeLocation="LocalMachine" storeName="My" x509FindType="FindByThumbprint" />
<serviceCertificate>
<authentication certificateValidationMode="None" />
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="Visible">
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceCredentials>
<serviceCertificate findValue="7da522dd75f3fca2687837b7b67e117a8700ec62" storeLocation="LocalMachine" storeName="My" x509FindType="FindByThumbprint"/>
<clientCertificate>
<certificate findValue="631f5a67a9a70bc78540bb809e73fd1dbd00bbeb" storeLocation="LocalMachine" storeName="My" x509FindType="FindByThumbprint"/>
</clientCertificate>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<basicHttpsBinding>
<binding name="BasicHttpsBinding" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
</basicHttpsBinding>
<wsHttpBinding>
<binding name="WSHttpBinding_IAcordWebService" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" useDefaultWebProxy="true" allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="65535" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
<binding name="WSHttpBinding_Mex" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" useDefaultWebProxy="true" allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="65535" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
</wsHttpBinding>
<netTcpBinding>
<binding name="NetTcpCertificatesBinding" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
<security>
<transport clientCredentialType="Certificate" protectionLevel="EncryptAndSign" />
</security>
</binding>
</netTcpBinding>
</bindings>
<protocolMapping>
<add binding="wsHttpBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
And here are the contents of the agent's app.config file:
<?xml version="1.0"?>
<configuration>
<configSections>
</configSections>
<system.serviceModel>
<client>
<endpoint address="net.tcp://local.someaddress.net:8122/AcordWebService/201309" behaviorConfiguration="NetTcpCertificatesBehavior" binding="netTcpBinding" bindingConfiguration="NetTcpCertificatesBinding" contract="AcordWSContract.IAcordWSService201309" name="AcordWSEndpoint">
<identity>
<certificateReference findValue="7da522dd75f3fca2687837b7b67e117a8700ec62" isChainIncluded="false" storeLocation="LocalMachine" x509FindType="FindByThumbprint" />
</identity>
</endpoint>
<endpoint address="net.tcp://qaschedapp:8001/IMS/201210" binding="netTcpBinding" bindingConfiguration="NetTcpWindowsBinding" contract="IdentityManagementContract.IIdentityManagementService201210" name="IMSEndpoint">
<!--the name above cannot be changed-->
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="net.tcp://qaschedapp:8012/CBS/201210" behaviorConfiguration="NetTcpCertificatesBehavior" binding="netTcpBinding" bindingConfiguration="NetTcpCertificatesBinding" contract="CrossbowContract.ICrossbowService201210" name="CBSEndpoint">
<identity>
<certificateReference findValue="7da522dd75f3fca2687837b7b67e117a8700ec62" isChainIncluded="false" storeLocation="LocalMachine" x509FindType="FindByThumbprint"/>
</identity>
</endpoint>
</client>
<diagnostics performanceCounters="Default"/>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpWindowsBinding">
<security mode="Transport">
<transport clientCredentialType="Windows"/>
</security>
</binding>
</basicHttpBinding>
<netTcpBinding>
<binding>
<readerQuotas maxDepth="32" maxStringContentLength="65535" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
</binding>
<binding name="NetTcpWindowsBinding" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:01:00" sendTimeout="00:10:00" transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions" hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxConnections="10" maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="32" maxStringContentLength="65535" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
<reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false"/>
<security mode="Transport">
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign"/>
<message clientCredentialType="Windows"/>
</security>
</binding>
<binding name="NetTcpCertificatesBinding" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
<security>
<transport clientCredentialType="Certificate" protectionLevel="EncryptAndSign"/>
</security>
</binding>
</netTcpBinding>
</bindings>
<services>
<service name="AcordAgent.AcordService" behaviorConfiguration="AcordServiceBehavior">
<endpoint address="http://qaschedapp:8100/Acord" binding="webHttpBinding" behaviorConfiguration="HttpWebGetBehavior" contract="AcordContract.IMeta" name="MetaEndpoint">
<!--the name of this endpoint above (MetaEndpoint) must stay-->
</endpoint>
<!--binding for clients within the firewall calling from C# with WCF -->
<endpoint address="net.tcp://qaschedapp:8101/Acord/201307" binding="netTcpBinding" bindingConfiguration="NetTcpWindowsBinding" name="NetTcpWindowsEndpoint" contract="AcordContract.IAcordService201307">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<!--binding for clients outside the firewall calling from C# with WCF using certs -->
<endpoint address="net.tcp://qaschedapp:8102/Acord/201307" binding="netTcpBinding" bindingConfiguration="NetTcpCertificatesBinding" name="NetTcpCertificatesEndpoint" contract="AcordContract.IAcordService201307">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="HttpWebGetBehavior">
<webHttp/>
</behavior>
<behavior name="NetTcpCertificatesBehavior">
<clientCredentials>
<clientCertificate findValue="631f5a67a9a70bc78540bb809e73fd1dbd00bbeb" storeLocation="LocalMachine" storeName="My" x509FindType="FindByThumbprint"/>
<serviceCertificate>
<authentication certificateValidationMode="None"/>
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="AcordServiceBehavior">
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceCredentials>
<serviceCertificate findValue="7da522dd75f3fca2687837b7b67e117a8700ec62" storeLocation="LocalMachine" storeName="My" x509FindType="FindByThumbprint"/>
<clientCertificate>
<certificate findValue="631f5a67a9a70bc78540bb809e73fd1dbd00bbeb" storeLocation="LocalMachine" storeName="My" x509FindType="FindByThumbprint"/>
</clientCertificate>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
</startup>
</configuration>
I found this in an IIS Express FAQ:
Q: Does IIS Express support non-HTTP protocols such as net.tcp or MSMQ?
A: No. IIS Express only supports HTTP and HTTPS as its protocol.
It seems like this is the root of my problem. I need to install IIS on my local machine.

WCF - Message credential vs TransportWithMessageCredential certificate verification

I'm having an interesting issue setting up a WCF service message credential security. I'm getting this exception on my client side:
An unhandled exception of type 'System.InvalidOperationException' occurred in mscorlib.dll
Additional information: The service certificate is not provided for target 'http://myMachine/SPTestService/Service1.svc'. Specify a service certificate in ClientCredentials.
This leads me to believe that I need to specify a server cert in my client config, but I'm not sure why. This should be using ChainTrust. Interestingly enough, when I switch it over to TransportWithMessageCredential (so it's working over SSL), it works, and correctly verifies the message credential as well. Is this a WCF bug? Fortunately, TransportWithMessageCredential was where I was heading, so I'll accelerate that process.
Using only Message credential, my configs look like this:
Client:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="serviceBehavior">
<clientCredentials>
<clientCertificate storeName="My" storeLocation="LocalMachine"
findValue="CN=myCert" />
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="serviceEndpoint" closeTimeout="00:01:00" openTimeout="00:01:00"
receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false"
bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Mtom" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="Message">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Certificate" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://myMachine/SPTestService/Service1.svc"
behaviorConfiguration="serviceBehavior"
binding="basicHttpBinding" bindingConfiguration="serviceEndpoint"
contract="ServiceReference2.IService1" name="serviceEndpoint" />
</client>
</system.serviceModel>
</configuration>
Service:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="serverBinding" messageEncoding="Mtom">
<security mode="Message">
<message clientCredentialType="Certificate" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="serviceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="true" />
<dataContractSerializer maxItemsInObjectGraph="2147483646" />
<serviceCredentials>
<serviceCertificate storeName="My" storeLocation="LocalMachine" findValue="CN=myCert" />
<clientCertificate>
<authentication revocationMode="NoCheck"/>
</clientCertificate>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="serviceBehavior" name="SPTestService.Service1">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="serverBinding" name="serviceEndpoint" contract="SPTestService.IService1" />
</service>
</services>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
Using TransportWithMessage, my configs look like this:
Client:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="serviceBehavior">
<clientCredentials>
<clientCertificate storeName="My" storeLocation="LocalMachine"
findValue="CN=myCert" />
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="serviceEndpoint" closeTimeout="00:01:00" openTimeout="00:01:00"
receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false"
bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Mtom" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Certificate" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://myMachine/SPTestService/Service1.svc"
behaviorConfiguration="serviceBehavior"
binding="basicHttpBinding" bindingConfiguration="serviceEndpoint"
contract="ServiceReference2.IService1" name="serviceEndpoint" />
</client>
</system.serviceModel>
</configuration>
Service:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="serverBinding" messageEncoding="Mtom">
<security mode="TransportWithMessageCredential">
<message clientCredentialType="Certificate" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="serviceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="true" />
<dataContractSerializer maxItemsInObjectGraph="2147483646" />
<serviceCredentials>
<serviceCertificate storeName="My" storeLocation="LocalMachine" findValue="CN=myCert" />
<clientCertificate>
<authentication revocationMode="NoCheck"/>
</clientCertificate>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="serviceBehavior" name="SPTestService.Service1">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="serverBinding" name="serviceEndpoint" contract="SPTestService.IService1" />
</service>
</services>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>

Setting up config files for WCF with SSL and certificates

I'm trying to set up a WCF webservice in IIS 7 with SSL and I'm a bit lost with config files.
I want the data from the server to the client to be garbled (Is this enough with SSL?)
The client will also need to identity itself to the server through a certificate.
I have the following certificates in place:
dev.test.com - accessing the url https://dev.test.com/TestService.svc shows that there is this valid certificate in place.
TestServer - a dummy certificate that identifies the server (Do I need really need this? Or perhaps I can reuse the dev.test.com? Maybe have server.test.com?)
TestClient - a dummy certificate on the client side
And this is how my config files are set up:
Web.config (Server):
<bindings>
<wsHttpBinding>
<binding name="wsHttpEndpointBinding"
messageEncoding="Mtom">
<security mode="Message">
<transport clientCredentialType="None" />
<message clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service
name="TestService"
behaviorConfiguration="TestServiceBehavior">
<endpoint
name="TestEndPoint"
address=""
binding="wsHttpBinding"
bindingConfiguration="wsHttpEndpointBinding"
bindingNamespace="http://www.example.com/"
contract="iWebService">
<!--<identity>
<dns value=""/>
</identity>-->
</endpoint>
<endpoint address="mex" binding="mexHttpsBinding" bindingConfiguration="" name="MexHttpsBindingEndpoint" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="TestServiceBehavior">
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" />
<serviceCredentials>
<clientCertificate>
<authentication certificateValidationMode="PeerOrChainTrust" />
</clientCertificate>
<serviceCertificate findValue="TestServer" storeLocation="LocalMachine"
storeName="My" x509FindType="FindBySubjectName" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
App.config (Client):
<bindings>
<wsHttpBinding>
<binding name="wsHttpBinding" bypassProxyOnLocal="false"
transactionFlow="false" hostNameComparisonMode="StrongWildcard"
messageEncoding="Mtom" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<reliableSession ordered="true"
enabled="false" />
<security mode="Message">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Certificate" negotiateServiceCredential="true"
algorithmSuite="Default" />
</security>
</binding>
<binding name="TestEndPoint" bypassProxyOnLocal="false"
transactionFlow="false" hostNameComparisonMode="StrongWildcard"
messageEncoding="Mtom"
textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
<reliableSession ordered="true"
enabled="false" />
<security mode="Transport">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Certificate" negotiateServiceCredential="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="https://dev.test.com/TestService.svc"
behaviorConfiguration="TestServiceBehavior"
binding="wsHttpBinding" bindingConfiguration="wsHttpBinding"
contract="IContractName" name="wsHttpBinding">
<identity>
<dns value="TestServer" />
</identity>
</endpoint>
<endpoint address="https://dev.test.com/DistributionCenterService.svc"
binding="wsHttpBinding" bindingConfiguration="TestEndPoint" contract="IContract.Name"
name="TestEndPoint" />
</client>
<behaviors>
<endpointBehaviors>
<behavior name="TestServiceBehavior">
<clientCredentials>
<clientCertificate findValue="TestClient"
storeName="My"
storeLocation="CurrentUser"
x509FindType="FindBySubjectName"/>
<serviceCertificate>
<authentication
certificateValidationMode="PeerOrChainTrust"
revocationMode="NoCheck"
trustedStoreLocation="CurrentUser"/>
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
When I try to access the https://dev.test.com/TestService.svc, I get
Could not find a base address that matches scheme http for the endpoint with binding WSHttpBinding. Registered base address schemes are [https].
Anyway, I'm really lost with what config setting I should be using.
I believe for you to be able to use https, your security mode on the wsHttpBinding for the client needs to be either Transport or (probably in your case) TransportWithMessageCredential.

WCF service using transport clientCredentialType Basic

I'm trying to create a wcf service which does basic authentication, but i'm having some troubles.
Here's what my web.config for the service looks like:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<client />
<services>
<service name="Service.DataExchangeService" behaviorConfiguration="MyBehavior">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsDataImportEndpoint" contract="Service.IDataExchangeService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8732/Design_Time_Addresses/DataExchange.Server.Service/Service1/" />
</baseAddresses>
</host>
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="wsDataImportEndpoint" maxBufferPoolSize="2147483647"
maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="32" maxStringContentLength="2147483647"
maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="Transport">
<transport clientCredentialType="Basic"/>
<message clientCredentialType="UserName" negotiateServiceCredential="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="MyBehavior">
<serviceMetadata httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceCredentials>
<userNameAuthentication customUserNamePasswordValidatorType="DataExchange.Server.Service.UserNameValidator, DataExchange.Server.Service"
userNamePasswordValidationMode="Custom" />
</serviceCredentials>
</behavior>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<connectionStrings>
<add name="ApplicationServices" connectionString="data source=sharept07\mssqlserver2008;initial catalog=VOS.Membership;integrated security=True;" providerName="System.Data.SqlClient" />
<add name="ROSEntities" connectionString="metadata=res://*/ROSModel.csdl|res://*/ROSModel.ssdl|res://*/ROSModel.msl;provider=System.Data.SqlClient;provider connection string="data source=sharept07\MSSQLServer2008;initial catalog=VOS;integrated security=True;multipleactiveresultsets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
</connectionStrings>
</configuration>
and here's what my client config file looks like:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IDataExchangeService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="2147483647"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Transport">
<transport clientCredentialType="Basic" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" negotiateServiceCredential="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="https://server.com:446/DataExchangeService/DataExchangeService.svc"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IDataExchangeService"
contract="DataExchangeSvc.IDataExchangeService" name="WSHttpBinding_IDataExchangeService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
and here's how i'm calling the service within my client:
static void Main(string[] args)
{
using (var client = new DataExchangeSvc.DataExchangeServiceClient())
{
client.ClientCredentials.UserName.UserName = "test";
client.ClientCredentials.UserName.Password = "test";
var data = client.RetrieveData();
}
}
When i set the the transport mode to "None" within security node in the Service config file the above works perfectly if i omit the credential lines, but the moment i change it to Basic i keep getting this error:
There was no endpoint listening at https://server.com:446/DataExchangeService/DataExchangeService.svc that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.
I don't really know what's going on so if anyone can guide me in any way that would be extremely helpful.
Thanks
I think what you really want here is to use TransportWithMessageCredential instead of just Transport. Just using <security mode="Transport"> will get your service going over HTTPS but has nothing to do with using credentials for authentication. If you use <security mode="TransportWithMessageCredential"> you can use HTTPS and have username and password. Here is an MSDN article about this.
EDIT
If you really do just want to use Transport, take out the <message> node from your service config.