Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WCF security authentication

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."}

like image 653
pdiddy Avatar asked Sep 01 '10 18:09

pdiddy


People also ask

How do I provide security to WCF?

To secure an application that runs exclusively on a Windows domain, you can use the default security settings of either the WSHttpBinding or the NetTcpBinding binding. By default, anyone on the same Windows domain can access WCF services. Because those users have logged on to the network, they are trusted.

What is WCF security?

Windows Communication Foundation (WCF) is a SOAP message-based distributed programming platform, and securing messages between clients and services is essential to protecting data.


2 Answers

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.

like image 53
Ronald Wildenberg Avatar answered Oct 06 '22 01:10

Ronald Wildenberg


I think Windows Authentication with WsHttpBinding only works with https.

See this: http://msdn.microsoft.com/en-us/library/ff650619.aspx

like image 20
stombeur Avatar answered Oct 06 '22 00:10

stombeur