Click here to Skip to main content
15,867,308 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
i was having difficulty getting this to work in a much larger project. so i put together the most simplistic bare bones WCF Service and Windows Client apps to test it out on. Still no success. This works with no issues if using clientCredentialType=Windows.
What i am attempting to do: implement a wsHttpBinding with Message Security mode with clientCredentialType=UserName and using a Custom UsernamePword validator routine. i have made other Sample Apps that use this same setup work fine...but none of those were using a Windows form client with Service Reference to a WCF Service, I have configured this in numerous ways, and i am just getting nowhere. Beginning to think i am attempting something that is just not supported/possible.

What i have:
1 WCF Service that has only 1 OperationContract/Function: PingService() that Returns TRUE. Service also contains the CustomValidator class and function that Overrides the default.
1 Windows application that has a ServiceReference to the above Service and is used to call PingService().
Created 2 x.509 certificates. gave access to these to IIS DefaultAppPool and imported these certs into IIS7.

Uisng: .Net Framework 4.0; IIS7; Default App Pool( >net FW 4 ); PassThrough Authentication;

When the Windows app attempts to call PingService(), this is the exception that is raised:
System.ServiceModel.Security.SecurityNegotiationException: The token provider cannot get tokens for target 'http://localhost/VinNowDataServiceLite/VinNowDataSvc.svc'. ---> System.ServiceModel.Security.SecurityNegotiationException: 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. ---> System.ServiceModel.FaultException: The request for security token has invalid or malformed elements.

This is the web.config for the Service:
XML
<system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name="Binding1" maxReceivedMessageSize="524288">
          <security mode="Message">
            <message clientCredentialType="UserName" establishSecurityContext="False" negotiateServiceCredential="false"/>
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    
    <services>
       <service name="VinNowDataSvc"
               behaviorConfiguration="Behavior1">
        <endpoint address="" binding="wsHttpBinding" bindingConfiguration="Binding1"
                  contract="IVinNowDataSvc" />
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost/VinNowDataServiceLite/VinNowDataSvc.svc" />
          </baseAddresses>
        </host>
      </service>
    </services>

    <protocolMapping>
      <add scheme="http" binding="wsHttpBinding" />
    </protocolMapping>

    <behaviors>
      <serviceBehaviors>
        <behavior>
        </behavior>
        <behavior name="Behavior1">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
          <serviceCredentials>
            <userNameAuthentication userNamePasswordValidationMode="Custom"
             customUserNamePasswordValidatorType="VinNowDataServiceLite.UserNamePassValidator, VinNowDataServiceLite" />
               <clientCertificate>
                <authentication certificateValidationMode="PeerTrust"/>
              </clientCertificate>
              <serviceCertificate findValue="localhost" storeLocation="CurrentUser" storeName="TrustedPeople" x509FindType="FindBySubjectName"/>
          </serviceCredentials>
         </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>


This is app.config for Windows client app:
XML
<system.serviceModel>
    <client>
      <endpoint address="http://localhost/VinNowDataServiceLite/VinNowDataSvc.svc"
            binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IVinNowDataServiceLite" behaviorConfiguration="CustomBehavior"
            contract="VNDataSvcLite.IVinNowDataServiceLite" name="WSHttpBinding_IVinNowDataServiceLite">
        <identity>
          <dns value="localhost"/>
        </identity>
      </endpoint>
    </client>
    
    <behaviors>
      <endpointBehaviors>
        <behavior name="CustomBehavior">
          <clientCredentials>
            <clientCertificate findValue="localclient" x509FindType="FindBySubjectName" storeLocation="CurrentUser" storeName="TrustedPeople"/>
            <serviceCertificate>
              <authentication certificateValidationMode="PeerTrust"/>
            </serviceCertificate>
          </clientCredentials>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <bindings>
              <wsHttpBinding>
                    <binding name="WSHttpBinding_IVinNowDataServiceLite" 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="UserName" negotiateServiceCredential="true"
                                      algorithmSuite="Default" establishSecurityContext="False"/>
                          </security>
                    </binding>
              </wsHttpBinding>
        </bindings>
    </system.serviceModel>
Posted
Comments
David Days 26-Feb-14 16:23pm    
Just guessing, but I'm betting that it's the "http://" address, as in "http://localhost/VinNowDataServiceLite/VinNowDataSvc.svc". wsHttpBinding looks for an SSL address by default, I believe.

You can get around this by changing your binding to <security mode="None"> at the security level.

The reason that it works for the Windows authentication is that Windows auth goes to an encrypted channel by default--so the negotiation is secured and the host doesn't complain. With a web service, the equivalent is an "https" address by default, which is not what you have.

I've had this problem many time, and it continues to bite me if I'm not paying attention--I'm just faster to fix it nowadays.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900