I have a simple service and I try to set up authentication. On the client I want the user to enter their Windows user account. And the WCF will use the username/password provided by the client and authenticate them against Windows authentication.
Here is my server app.config
<system.serviceModel>
<services>
<service name="WcfService.Service1" behaviorConfiguration="WcfService.Service1Behavior">
<host>
<baseAddresses>
<add baseAddress = "http://localhost:8731/Design_Time_Addresses/WcfService/Service1/" />
</baseAddresses>
</host>
<endpoint address ="" binding="wsHttpBinding" contract="WcfService.IService1">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WcfService.Service1Behavior">
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="True" />
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode = "Windows"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Here is my client app.config
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IService1">
<security mode = "Message">
<message clientCredentialType = "UserName"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:8731/Design_Time_Addresses/WcfService/Service1/"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService1"
contract="ServiceReference1.IService1" name="WSHttpBinding_IService1">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
</system.serviceModel>
Here is my code on the client
ServiceReference1.Service1Client client = new WcfAuthentication.ServiceReference1.Service1Client();
client.ClientCredentials.UserName.UserName = "mywindowsusername";
client.ClientCredentials.UserName.Password = "mywindowsuserpassword";
Console.WriteLine(client.GetData(5));
But I'm always getting this exception :
{"Secure channel cannot be opened because security negotiation with the remote endpoint has failed. This may be due to absent or incorrectly specified EndpointIdentity in the EndpointAddress used to create the channel. Please verify the EndpointIdentity specified or implied by the EndpointAddress correctly identifies the remote endpoint. "} {"The request for security token has invalid or malformed elements."}
It looks like you generated the service and client configuration separately (by hand). It usually is a good idea to generate the client configuration from the service using svcutil
or Visual Studio's 'Add Service Reference'. This way you know that you get the client config that corresponds to the service config.
What you want is possible, but WCF doesn't allow you to transmit your username/password token in plain text when using wsHttpBinding
. This means that you must either host your service using https or use a service certificate. Here's a post with some more details.
But I'm also wondering why you would want anything like this. It may be a better idea to use integrated Windows authentication. This is even the default setting for wsHttpBinding
. This way you do not need your client(s) to enter their Windows username/password.