WCF service connection error: "The request for security token has invalid or malformed elements" - wcf

I set up certificate-based authentication for a WCF service. It works when the service and the client are running on the same computer, but now I have deployed them to different computers, I encounter "The request for security token has invalid or malformed elements".
It seems like this is usually a certificate error. I don't see what is wrong with the setup.
The server has the following certificates installed:
MyRoot in Local Machine\Trusted CAs
MyServer in Local Machine\Personal (with the private key)
The client has the following certificates installed:
MyRoot in Local Machine\Trusted CAs
MyClientCert in Local Machine\Personal (with the private key)
The client configuration is like this:
<system.serviceModel>
<client>
<endpoint address="http://10.0.0.4:8000/Handshake" binding="wsHttpBinding" behaviorConfiguration="ClientCertificateBehavior"
bindingConfiguration="WSHttpBinding_IHandshaker" contract="IHandshaker"
name="WSHttpBinding_IHandshaker"/>
</client>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IHandshaker">
<security>
<message clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="ClientCertificateBehavior">
<clientCredentials>
<clientCertificate findValue="MyClientCert" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName"/>
<serviceCertificate>
<authentication certificateValidationMode="PeerOrChainTrust" revocationMode="NoCheck"/>
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
The service configuration is like this:
<system.serviceModel>
<bindings>
<customBinding>
<binding name="gzipBinding">
<gzipMessageEncoding />
<sslStreamSecurity />
<tcpTransport>
</tcpTransport>
</binding>
</customBinding>
<wsHttpBinding>
<binding name="ClientCertAuthenticationBinding">
<security mode="Message">
<message clientCredentialType="Certificate"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="Rdt.CertificateIdentification.ClientAuthentication.HandshakeService" behaviorConfiguration="HandshakeServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="http://10.0.0.4:8000/Handshake"/>
</baseAddresses>
</host>
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="ClientCertAuthenticationBinding" contract="OCS.Client.KnownLayer.IHandshaker"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="HandshakeServiceBehavior">
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="True"/>
<serviceCredentials>
<serviceCertificate findValue="MyServer" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName"/>
<clientCertificate>
<authentication certificateValidationMode="ChainTrust" revocationMode="NoCheck"/>
</clientCertificate>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>

1.You need to specify the DNS value in the client configuration, WcfServer is the name of your server certificate,here is a tutorial on how to use the certificate correctly.
<client>
<endpoint address="" binding="" bindingConfiguration="" contract="" name="" behaviorConfiguration="">
<identity>
<dns value="WcfServer" />
</identity>
</endpoint>
</client>
2.There is one more </client> in your service configuration.
3.You can try to set <security mode="Message"> in the client configuration.

Related

request for a specific client certificate in nettcp bindings

Is it possible to configure net tcp binding
to request a specific certificate to be supplied by the client ?
not just certificate which is trusted by the server but the exact same certificate defined in the server ?
Thanks
You use netTcpBinding and need a specific certificate to verify, you can view my demo.
This is the app.config in service:
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<services>
<service name="Microsoft.Samples.X509CertificateValidator.CalculatorService" behaviorConfiguration="CalculatorServiceBehavior">
<!-- use host/baseAddresses to configure base address provided by host -->
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:8040/servicemodelsamples/service"/>
</baseAddresses>
</host>
<!-- use base address specified above, provide one endpoint -->
<endpoint address="certificate" binding="netTcpBinding" bindingConfiguration="Binding" contract="Microsoft.Samples.X509CertificateValidator.ICalculator"/>
</service>
</services>
<bindings>
<netTcpBinding>
<!-- X509 certificate binding -->
<binding name="Binding">
<security mode="Transport">
<transport clientCredentialType="Certificate"/>
</security>
</binding>
</netTcpBinding>
</bindings>
In the behavior node, we can specify the information of the certificate to be used.
<behaviors>
<serviceBehaviors>
<behavior name="CalculatorServiceBehavior">
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceCredentials>
<clientCertificate>
<authentication certificateValidationMode="Custom" customCertificateValidatorType="Microsoft.Samples.X509CertificateValidator.CustomX509CertificateValidator, service"/>
</clientCertificate>
<serviceCertificate findValue="localhost" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>
This is the app.config in client:
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<client>
<!-- X509 certificate based endpoint -->
<endpoint name="Certificate" address="net.tcp://localhost:8040/servicemodelsamples/service/certificate" binding="netTcpBinding" bindingConfiguration="Binding" behaviorConfiguration="ClientCertificateBehavior" contract="Microsoft.Samples.X509CertificateValidator.ICalculator">
</endpoint>
</client>
<bindings>
<netTcpBinding>
<!-- X509 certificate binding -->
<binding name="Binding">
<security mode="Transport">
<transport clientCredentialType="Certificate"/>
</security>
</binding>
</netTcpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="ClientCertificateBehavior">
<clientCredentials>
<serviceCertificate>
<authentication certificateValidationMode="PeerOrChainTrust"/>
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>
In client.cs, we need to specify the certificate to be used through the setcertificate method.
client.ClientCredentials.ClientCertificate.SetCertificate(StoreLocation.CurrentUser, StoreName.My, X509FindType.FindBySubjectName, "alice");

Could not find a base address that matches scheme http for the endpoint with binding WSHttpBinding with NO SOLUTION YET

I have a WCF Service (with authentication and authorization) hosting in IIS 7.5 using SSL certification in Windows Server 2008 R2. I got error while running the WCF application with Visual Studio in this server. WCF Test Client gave me this error: Could not find a base address that matches scheme https for the endpoint with binding WSHttpBinding. But Its working in IIS. And I can deploy my WCF service in my web application with no error. All suggestions were tried and had no solution.
My web.config:
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="wsHttpEndpointBinding">
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None"/>
<message clientCredentialType="UserName"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="ServiceBehavior" name="TBBWS.TBBService">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsHttpEndpointBinding"
name="wsHttpEndpoint" contract="TBBWS.ITBBService" />
<endpoint address="mex" binding="mexHttpsBinding" bindingConfiguration=""
name="MexHttpsBindingEndpoint" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="TBBWS.CustomValidation, App_Code" />
</serviceCredentials>
<serviceAuthorization principalPermissionMode="Custom">
<authorizationPolicies>
<add policyType="TBBWS.CustomAuthorizationPolicy, App_Code" />
</authorizationPolicies>
</serviceAuthorization>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<remove scheme="http" />
<add binding="wsHttpBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
Any suggestions about it?
Ok, I got it. For those who need help because of the same problem:
1)I added <serviceCertificate storeLocation="LocalMachine" storeName="My" findValue="bla bla bla" x509FindType="FindByThumbprint" /> under serviceCredentials tag.
2)I defined 2 bindings. http and https. I removed http binding.
Thanks anyway...

Pass ClientCredentials.UserName to server

Web config:
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceCredentialsBehavior">
<serviceCredentials>
<serviceCertificate findValue="cool" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName"/>
</serviceCredentials>
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="ServiceCredentialsBehavior" name="Service">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="MessageAndUserName" name="SecuredByTransportEndpoint" contract="IService"/>
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="MessageAndUserName">
<security mode="Message">
<message clientCredentialType="UserName"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<client/>
</system.serviceModel>
<system.web>
<compilation debug="true"/>
</system.web>
Client cfg:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IService" >
<security mode="Message">
<message clientCredentialType="UserName" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:48097/WCFServer/Service.svc"
binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_IService"
contract="ServiceReference1.IService"
name="WSHttpBinding_IService">
<identity>
<dns value ="cool" />
</identity>
</endpoint>
</client>
</system.serviceModel>
The scope is to pass ClientCredentials.UserName.UserName/Password through a secure connection.
I did x509 certificates with pluralsight self cert..
The error is:
SOAP security negotiation with 'http://localhost:48097/WCFServer/Service.svc'
for target
'http://localhost:48097/WCFServer/Service.svc'
failed. See inner exception for more
details.
InnerException:
The X.509 certificate CN=cool chain
building failed. The certificate that
was used has a trust chain that cannot
be verified. Replace the certificate
or change the
certificateValidationMode. A
certificate chain processed, but
terminated in a root certificate which
is not trusted by the trust provider.
How can i solve this exception?
Regards,
Sergiu.
You are using self signed certificate which is not trusted by default. You must tell your client application that it should trust the certificate:
<behaviors>
<endpointBehaviors>
<behavior name="LocalCertValidation">
<clientCredentials>
<serviceCertificate>
<authentication certificateValidationMode="PeerTrust" />
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
Reference this behavior from your endpoint configuration in client by behaviorConfiguration="LocalCertValidation". To make it work you must install public certificate to current user's certification store under trusted people. You can also set validation mode to None and certificate will not be validated at all but that should be used only in development environment.

WCF problem with POSTs using ssl (https)

I currently have a webHttp binding WCF restful service, it works great over http, I can make Post of large sizes due to my webconfig settings, now I am trying to use it over https (ssl), now my gets work fine, but my posts dont, it doesnt work when the file size is over a certain amount, i was wondering why this could be since my webconfig specifies a larger size and it works good over http, here is my relevant webconfig.. any suggestions
Thanks
<system.serviceModel>
<client>
<endpoint binding="webHttpBinding" bindingConfiguration="webHttp"
contract="PrimeStreamInfoServices.IService1" name="Client" />
</client>
<bindings>
<webHttpBinding>
<binding name="webHttp" maxBufferSize="15000000" maxBufferPoolSize="15000000"
maxReceivedMessageSize="15000000">
<readerQuotas maxDepth="15000000" maxStringContentLength="10000000"
maxArrayLength="15000000" maxBytesPerRead="15000000" maxNameTableCharCount="10000000" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="string" />
</security>
</binding>
</webHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="PrimeStreamInfoServices.Service1Behavior"
name="PrimeStreamInfoServices.Service1">
<endpoint address="" binding="webHttpBinding"
bindingConfiguration="webHttp" contract="PrimeStreamInfoServices.IService1" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="PrimeStreamInfoServices.Service1Behavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
<serviceCredentials>
<!--
<serviceCertificate storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" findValue="TempCa" />
-->
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<diagnostics>
<messageLogging logMalformedMessages="true" logMessagesAtServiceLevel="true"
logMessagesAtTransportLevel="true" />
</diagnostics>
If you want to use webHttpBinding over SSL then you have configure your binding to use transport security like:
<security mode="Transport">
This link provides some details with sample config to deal with the following error:
Could not find a base address that matches scheme http for the
endpoint with binding WebHttpBinding. Registered base address schemes
are [https]
Sample config from the blog:
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="TestServiceAspNetAjaxBehavior">
<enableWebScript />
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
<services>
<service name="TestService">
<endpoint address="" behaviorConfiguration="TestServiceAspNetAjaxBehavior"
binding="webHttpBinding" bindingConfiguration="webBinding" contract="TestService" />
</service>
</services>
<bindings>
<webHttpBinding>
<binding name="webBinding">
<security mode="Transport">
</security>
</binding>
</webHttpBinding>
</bindings>
</system.serviceModel>

WebHttpBinding Security Question

I have created a RESTful Service and implemented the Authentication. It accepts username and password and then grants access to the service requested. It Works fine. Now I want to use SSL on top of my Service. For this I Created Certificate, Then In IIS I gave the required settings. But my service is not working. I am using webHttpBinding.
my Web.Config on service side is :
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
<services>
<service behaviorConfiguration="ServiceBehavior" name="TestAPI">
<host>
<baseAddresses>
<add baseAddress="https://localhost/AuthWithSSLTest/API/TestAPI.svc" />
</baseAddresses>
</host>
<endpoint address="" behaviorConfiguration="RESTFriendly" bindingConfiguration="MywebHttpBinding" binding="webHttpBinding" contract="ITestAPI" >
</endpoint>
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
</service>
</services>
<client /><bindings>
<webHttpBinding>
<binding name="MywebHttpBinding">
<security mode="Transport" >
<transport clientCredentialType="Certificate"/>
</security>
</binding>
</webHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="RESTFriendly">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceCredentials>
<clientCertificate>
<authentication revocationMode="NoCheck" />
</clientCertificate>
<serviceCertificate findValue="CN=tempCertClient" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
And In my client side app.config I have
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="NewBehavior">
<clientCredentials>
<clientCertificate findValue="CN=tempCertClient" storeLocation="LocalMachine" />
<serviceCertificate>
<authentication certificateValidationMode="PeerTrust" revocationMode="NoCheck" />
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<customBinding>
<binding name="WebHttpBinding_ITestAPI">
<httpTransport/>
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="https://localhost/AuthWithSSLTest/API/API.svc/TestMethod"
behaviorConfiguration="NewBehavior" binding="customBinding"
bindingConfiguration="WebHttpBinding_ITestAPI"
contract="TestAPI.ITestAPI" name="WebHttpBinding_ITestAPI" />
</client>
</system.serviceModel>
When I try to Run Client, it says Provided URI scheme Https is invalid, http required.
Also when I try to invoke the Web Service from VS2008, it says "Could not find a base address that matches scheme https for the endpoint with binding WebHttpBinding. Registered base address schemes are [http]."
if I try to run the web service from IIS, it says "Could not find a base address that matches scheme http for the endpoint with binding WebHttpBinding. Registered base address schemes are [https]."
I have tried googling and tried all the suggested things, but no awail. Please Help.
Thanks in Advance,
Tara Singh
In your client configuration, try changing:
<httpTransport/>
to:
<httpsTransport/>