WCF and custom Authentication (username/password) - c#

I have Windows Forms clients that connect to a WCF service over the internet.
WCF service is hosted in a Windows Service running under dedicated Windows account.
I want to authenticate the clients against database by checking username+password pair.
In order to avoid hundreds of methods like:
public int Add(string User, string Password, int A, int B)
I used the following guide to override UserNamePasswordValidator class:
http://blog.clauskonrad.net/2011/03/how-to-wcf-and-custom-authentication.html
My custom authenticator class matches the example
class UsernameAuthentication : UserNamePasswordValidator
{
public override void Validate(string userName, string password)
{
//Will be checked against database
var ok = (userName == "Ole") && (password == "Pwd");
if (ok == false)
throw new AuthenticationException("u/p does not match");
}
}
My server config is:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
<system.serviceModel>
<services>
<service name="TestWCFCustomAuth.CalculatorService" behaviorConfiguration="customCred">
<endpoint address="CalcSvc"
binding="netTcpBinding"
bindingConfiguration="secUP"
contract="ServiceInterface.ICalculatorService"/>
<endpoint address="mex" binding="mexHttpBinding" contract="ServiceInterface.ICalculatorService" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:81/"/>
<add baseAddress="net.tcp://localhost:82/"/>
</baseAddresses>
</host>
</service>
</services>
<bindings>
<netTcpBinding>
<binding name="secUP">
<security mode="Message">
<message clientCredentialType="UserName"/>
</security>
</binding>
</netTcpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="customCred">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceCredentials>
<!--Service identity + encryption certificate-->
<serviceCertificate findValue="SHKIService" storeLocation="LocalMachine" storeName="Root" x509FindType="FindBySubjectName"/>
<userNameAuthentication userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="TestWCFCustomAuth.UsernameAuthentication, TestWCFCustomAuth" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
And the client is auto-generated:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_ICalculatorService">
<security mode="Message">
<transport sslProtocols="None" />
<message clientCredentialType="UserName" />
</security>
</binding>
</netTcpBinding>
<wsHttpBinding>
<binding name="MetadataExchangeHttpBinding_ICalculatorService">
<security mode="None" />
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="net.tcp://localhost:82/CalcSvc" binding="netTcpBinding"
bindingConfiguration="NetTcpBinding_ICalculatorService" contract="ServiceReference1.ICalculatorService"
name="NetTcpBinding_ICalculatorService">
<identity>
<certificate encodedValue="AwAAAAEAAAAUAAAA5Miz/2tl3pOxgQepIM62wzcAU+8gAAAAAQAAAK0BAAAwggGpMIIBCqADAgECAgkArWjRy0f0w98wCgYIKoZIzj0EAwIwFjEUMBIGA1UEAxMLU0hLSVNlcnZpY2UwHhcNMjEwMzI5MjEzNjUwWhcNMjYwMzI5MjEzNjUwWjAWMRQwEgYDVQQDEwtTSEtJU2VydmljZTCBmzAQBgcqhkjOPQIBBgUrgQQAIwOBhgAEAXE/ZelSAJ7+qjUTECzz2ZHFHTd6KtYsrbgdvBw3Xqt/G9R4IO01Rvxltir7FMfHzLgzsa4LdLkY3yAk/4rOqTPqAXY/sd/TpZOOB7ntZx02BEUvNiKouVu+yzIBMQxyW4aGZGOftiSOA28VKxNnaARN97/IoYyO0FhN+4vlKaPlTGFQMAoGCCqGSM49BAMCA4GMADCBiAJCAa88D2F5LuEFF0BL2+Vn1xIGSrjLo1YpiJk0DNJEbF0OOzH+xuKk/8H4yjQGO/yMmI8/pQWeU36Bu/D2xxJ0XqvtAkIA9udnx+h7lAsAYOtFMT12qHkVHInGWTzGHjNF0nrOldURa7X8B+tDeYrDJGBD+/9R2E4koJeGb0ubAmUl4Hrwyik=" />
</identity>
</endpoint>
<endpoint address="http://localhost:81/mex" binding="wsHttpBinding"
bindingConfiguration="MetadataExchangeHttpBinding_ICalculatorService"
contract="ServiceReference1.ICalculatorService" name="MetadataExchangeHttpBinding_ICalculatorService" />
</client>
</system.serviceModel>
</configuration>
I made a self-signed certificate and imported it into the Root directory, so the certificate configuration is OK too.
Test-client code is:
var client = new CalculatorServiceClient("NetTcpBinding_ICalculatorService");
client.ClientCredentials.UserName.UserName = "Ole";
client.ClientCredentials.UserName.Password = "Pwd";
var res = client.Add(1, 2);
Console.WriteLine("Result: {0}", res);
Although my code is nearly identical to the guide, I get an error:
System.ServiceModel.Security.SecurityNegotiationException: 'The caller was not authenticated by the service.'
Inner Exception:
FaultException: The request for security token could not be satisfied because authentication failed.
I searched for an answer for several days and tried many other configurations. My best guess is that there is some other kind of authentication happening behind the scenes? If that's so - how do I disable that?

There is a complete demo in the official documentation, which uses username and password verification, and also has certificate verification. You only need to follow the steps in the tutorial to run successfully. You can refer to the reference.

The steps I was missing are as follows:
Give the Windows service account a "Read" permission to certificate's private key as described here here
at
To grant permission on the private key to the account one can use
Certificate Snap-In of mmc. One can start mms.exe, choose "Add/Remove
Snap-in" in the "File" menu, choose "Certificates" Snap-in and to
choose "Computer account" of the Local computer. Then one should
select the SSL certificate of Personal store and then use context menu
"Manage Private Keys...".
The computer running a client app needs to have the certificate in CurrentUser\Trusted People store (even if the client and server are running on the same computer). So I used mmc tool from previous step to export the certificate without private key into a file and then imported certificate from that file into CurrentUser\Trusted People store. I suppose I'll have to include this file into my client's installation package.
Also this time I used makecert.exe tool to create certificate as suggested in the msdn reference provided by #Theobald Du
The commands are:
makecert.exe -sr LocalMachine -ss MY -a sha1 -n CN=<I used server's IP address> -sky exchange -pe
P.S. Also I was missing makecert.exe on that machine, so I downloaded Microsoft SDKs from microsoft

Related

Self Hosting WCF service using app.Config files

I have self hosting WCF service that contains it's own app.Config to expose endpoints required for the service contracts. If the service is started in the programs.cs main method it all works just fine and the metadata is exposed via the browser. However, I created a HostService class based on the ServiceBase class which in the same host library and is instantiated within the program.cs file. The HostService class starts the service and has a timer method to ping other client web services for information.
My question is, when I created the HostService : ServiceBase class and instantiate it from the main(), I have to put a duplicate app.Config file in the Service Library in order for the endpoints to properly exposed and return the metadata/wsdl. I don't want to maintain 2 duplicate app.config files if possible. Currently the host library and service library both require one. Is there a way to only have just one w/ the host that could be used for both? Sorry for the dumb question, but I'm new to WCF =)
Program.cs
static void Main(string[] args){
var service = new HostService();
service.StartHostService(args);
}
HostService.cs
public partial class HostService : ServiceBase
{
internal void StartHostService(string[] args)
{
this.OnStart(args);
Console.ReadLine();
this.OnStop();
}
....
}
Short answer is no. There must be two configs, one for the client that consumes the WCF and one for the server that exposes that communication methods with the WCF.
In order for your client to work, your config must be set with Client Configuration
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.serviceModel>
<client>
<endpoint
name="endpoint1"
address="http://localhost/ServiceModelSamples/service.svc"
binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_IHello"
behaviorConfiguration="IHello_Behavior"
contract="IHello" >
<metadata>
<wsdlImporters>
<extension
type="Microsoft.ServiceModel.Samples.WsdlDocumentationImporter, WsdlDocumentation"/>
</wsdlImporters>
</metadata>
<identity>
<servicePrincipalName value="host/localhost" />
</identity>
</endpoint>
// Add another endpoint by adding another <endpoint> element.
<endpoint
name="endpoint2">
//Configure another endpoint here.
</endpoint>
</client>
//The bindings section references by the bindingConfiguration endpoint attribute.
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IHello"
bypassProxyOnLocal="false"
hostNameComparisonMode="StrongWildcard">
<readerQuotas maxDepth="32"/>
<reliableSession ordered="true"
enabled="false" />
<security mode="Message">
//Security settings go here.
</security>
</binding>
<binding name="Another Binding"
//Configure this binding here.
</binding>
</wsHttpBinding>
</bindings>
//The behavior section references by the behaviorConfiguration endpoint attribute.
<behaviors>
<endpointBehaviors>
<behavior name=" IHello_Behavior ">
<clientVia />
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
notice the <client> tag specifying how the client must call the WCF.
and with Server Config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="myBindingConfiguration1" closeTimeout="00:01:00" />
<binding name="myBindingConfiguration2" closeTimeout="00:02:00" />
<binding closeTimeout="00:03:00" /> <!—- Default binding for basicHttpBinding -->
</basicHttpBinding>
</bindings>
<services>
<service name="MyNamespace.myServiceType">
<endpoint
address="myAddress" binding="basicHttpBinding"
bindingConfiguration="myBindingConfiguration1"
contract="MyContract" />
<endpoint
address="myAddress2" binding="basicHttpBinding"
bindingConfiguration="myBindingConfiguration2"
contract="MyContract" />
<endpoint
address="myAddress3" binding="basicHttpBinding"
contract="MyContract" />
</service>
</services>
</system.serviceModel>
</configuration>
Notice there is no <client> tag here.

No endpoint listening at local "..."

I have been given a wcf service, and i built a local console applicattion to test it, but i keep getting this error shown in the title. My service runs in the browser as it should, showing the screen where it shows the example and the url where you can test it. Probably the error is in the Web.config or in the App.config. I have this two files:
Web.condig
<?xml version="1.0"?>
<configuration>
<appSettings>
...
</appSettings>
<system.web>
<compilation debug="false" targetFramework="4.0"/>
</system.web>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="webHttpBindingWithJsonP" crossDomainScriptAccessEnabled="true"/>
</webHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="webHttpBehavior">
<webHttp helpEnabled="true"/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
<services>
<service name="RAHPEDWCFService.RAHPEDService">
<endpoint address="http://localhost:44184/RAHPEDService.svc" behaviorConfiguration="webHttpBehavior" binding="webHttpBinding" bindingConfiguration="webHttpBindingWithJsonP" contract="RAHPEDWCFService.IRAHPEDService"/>
</service>
</services>
</system.serviceModel>
</configuration>
App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IRAHPEDService" 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="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192"
maxArrayLength="16384" maxBytesPerRead="4096"
maxNameTableCharCount="16384" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:44184/RAHPEDService.svc"
binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IRAHPEDService"
contract="ServiceReference.IRAHPEDService"
name="BasicHttpBinding_IRAHPEDService" />
</client>
</system.serviceModel>
</configuration>
I hope someone could give me a hint.
Please follow the below steps to resolve it
Please browse your service and click on the Url whether it is showing the metadata or not.
ex:http: //oj:23/Myservice?wsdl
If metadata is not enabled then do the below changes to your service config file.
i. create a mex endpoint
ii. Name the service behavior
Ex:
< serviceBehaviors>
< behavior name="SerBehavior">
< serviceMetadata httpGetEnabled="true"/>
< /behavior>
< /serviceBehaviors>
iii. Add this behavior to your service
Ex:
< service name="RAHPEDWCFService.RAHPEDService" behaviorConfiguration="SerBehavior"> < /service>
iv. Build the service and browse click on url to check the metaData
In your console application right click on the project and click on Add Service Reference
Place the Url in the Address box, click on Go check whether you are able to see the service, select your service and give namespace and click OK
create the object of your ServiceClient
Call your method
able to see the wsdl metadata in the browser.
If you have multiple endpoints in your client configuration file then you have pass the name of the endpoint to the constructor of ServiceCleint Class
Open Visual studio CommandPrompt and type WcfTestClient, right click on MyServiceProjects, add the service and check whether you are able to add or not and once added call your method under the endpoint appears
You should check that you are accessing the correct address. Rather than specify the entire address in the Web.config, more common practice is to provide just a relative address (even
an empty "" is fine), and then you access the service with:
http://servername:[port]/[virtual directory]/RAHPEDWCF.svc/[relative address in Web.config]
E.g. if address in Web.config showed
endpoint address="MySVC"
the full URL for clients (assuming default port 80 and in root of virtual server) might be
http://servername/RAHPEDWCF.svc/MySVC
If you are able to modify Web.config, this is what I would advise.

WCF Streaming: Framing mode error in net.tcp only

I have one application server implementing a bunch of services using default transferMode="Buffered" and one Streamed service. It exposes endpoints for basicHttp and net.tcp protocols, and runs in production under dozens of IIS 7.0+ configurations without incident.
When I went to replicate the architecture for a new application's server, streaming over net.tcp simply refused to work, throwing the perfectly opaque and obtuse ProtocolException
The .Net Framing mode being used is not supported by MyNetTcpEndpointAddress. See the server logs for more details.
Yeah right, the "server logs". (There's nothing, whether traced or not.) Service architectures and web.configs for S1 and S2 are identical, except for
some name changes
a custom namespace in S2 (S1 using tempuri)
different ports (S1 and S2 both using ports in the 8000-9000 range)
Streaming service S2 works just fine under basicHttp.
Having tried everything and failed to make the error go away, I built a test client that does nothing but run my service architecture with some Ping methods. No custom namespace, no frills, just the original configs, and lite services, contracts, and hand-coded wrappers around the ChannelFactory proxies.
Same error:
The .Net Framing mode being used is not supported by 'net.tcp://localhost:9931/StreamingService.svc'. See the server logs for more details.
The buffered test service works under both protocols, and the streamed service works under basicHttp, as in S2.
All testing done on the same Win7 machine with a complete IIS setup. The test app is still too big to post here, but here are the complete configs, and the console code
web.config
<configuration>
<connectionStrings>
</connectionStrings>
<system.web>
<compilation debug="true" targetFramework="4.0" />
<!-- throttling of stream size is partially controlled by this setting -->
<httpRuntime maxRequestLength="1048576" /><!-- 1GB -->
</system.web>
<system.serviceModel>
<serviceHostingEnvironment>
<serviceActivations>
<add relativeAddress="FooService.svc" service="WcfTest.Services.FooService" />
<add relativeAddress="StreamingService.svc" service="WcfTest.Services.StreamingService" />
</serviceActivations>
</serviceHostingEnvironment>
<behaviors>
<serviceBehaviors>
<behavior>
<dataContractSerializer maxItemsInObjectGraph="200000" />
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding
openTimeout="00:20:00" sendTimeout="00:20:00" receiveTimeout="00:20:00" closeTimeout="00:20:00"
maxBufferSize="20000000" maxBufferPoolSize="20000000" maxReceivedMessageSize="20000000">
<readerQuotas maxStringContentLength="12000" />
</binding>
<binding name="WcfTest.Streaming.Http" transferMode="Streamed"
openTimeout="03:00:00" sendTimeout="03:00:00" receiveTimeout="03:00:00" closeTimeout="03:00:00"
maxReceivedMessageSize="1073741824" /><!-- 1GB -->
</basicHttpBinding>
<netTcpBinding>
<binding
openTimeout="00:20:00" sendTimeout="00:20:00" receiveTimeout="00:20:00" closeTimeout="00:20:00"
maxBufferSize="20000000" maxBufferPoolSize="20000000" maxReceivedMessageSize="20000000">
<readerQuotas maxStringContentLength="12000" />
</binding>
<binding name="WcfTest.Streaming.Tcp" transferMode="Streamed"
openTimeout="03:00:00" sendTimeout="03:00:00" receiveTimeout="03:00:00" closeTimeout="03:00:00"
maxReceivedMessageSize="1073741824"><!-- 1GB -->
</binding>
</netTcpBinding>
</bindings>
<protocolMapping>
<add scheme="http" binding="basicHttpBinding" />
<add scheme="net.tcp" binding="netTcpBinding"/>
</protocolMapping>
<services>
<service name="WcfTest.Services.Streaming">
<!-- http -->
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="WcfTest.Streaming.Http" contract="WcfTest.Contracts.IStreamingService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<!-- net.tcp -->
<endpoint address="" binding="netTcpBinding" bindingConfiguration="WcfTest.Streaming.Tcp" contract="WcfTest.Contracts.IStreamingService" />
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
</service>
</services>
</system.serviceModel>
</configuration>
app.config
<configuration>
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior>
<dataContractSerializer maxItemsInObjectGraph="200000"/>
</behavior>
<behavior name="customQuotaBehavior">
<dataContractSerializer maxItemsInObjectGraph="2147483646"/>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding
openTimeout="00:20:00" sendTimeout="00:20:00" receiveTimeout="00:20:00" closeTimeout="00:20:00"
maxBufferSize="20000000" maxBufferPoolSize="20000000" maxReceivedMessageSize="20000000">
<readerQuotas maxStringContentLength="12000" />
</binding>
<binding name="WcfTest.Bindings.Streaming.Http" transferMode="Streamed"
openTimeout="03:00:00" sendTimeout="03:00:00" receiveTimeout="03:00:00" closeTimeout="03:00:00"
maxReceivedMessageSize="1073741824"><!-- 1GB -->
</binding>
</basicHttpBinding>
<netTcpBinding>
<binding
openTimeout="00:20:00" sendTimeout="00:20:00" receiveTimeout="00:20:00" closeTimeout="00:20:00"
maxBufferSize="20000000" maxBufferPoolSize="20000000" maxReceivedMessageSize="20000000">
<readerQuotas maxStringContentLength="12000" />
</binding>
<binding name="WcfTest.Bindings.Streaming.Tcp" transferMode="Streamed"
openTimeout="03:00:00" sendTimeout="03:00:00" receiveTimeout="03:00:00" closeTimeout="03:00:00"
maxReceivedMessageSize="1073741824"><!-- 1GB -->
</binding>
</netTcpBinding>
</bindings>
<client>
<!-- Foo -->
<endpoint name="WcfTest.Endpoints.Foo.Http" address="http://localhost:9930/FooService.svc" binding="basicHttpBinding" contract="WcfTest.Contracts.IFooService" />
<endpoint name="WcfTest.Endpoints.Foo.Tcp" address="net.tcp://localhost:9931/FooService.svc" binding="netTcpBinding" contract="WcfTest.Contracts.IFooService" />
<!-- Streaming -->
<endpoint name="WcfTest.Endpoints.Streaming.Http" address="http://localhost:9930/StreamingService.svc" binding="basicHttpBinding" bindingConfiguration="WcfTest.Bindings.Streaming.Http" contract="WcfTest.Contracts.IStreamingService" />
<endpoint name="WcfTest.Endpoints.Streaming.Tcp" address="net.tcp://localhost:9931/StreamingService.svc" binding="netTcpBinding" bindingConfiguration="WcfTest.Bindings.Streaming.Tcp" contract="WcfTest.Contracts.IStreamingService" />
</client>
</system.serviceModel>
</configuration>
console test call
static void Main(string[] args)
{
Console.WriteLine("starting WcfTest client...");
Console.WriteLine();
PingFoo(Contracts.Enums.Protocol.Http);
PingFoo(Contracts.Enums.Protocol.Tcp);
Console.WriteLine();
PingStreaming(Contracts.Enums.Protocol.Http);
// only this call errors:
PingStreaming(Contracts.Enums.Protocol.Tcp);
Console.WriteLine();
Console.Write("ENTER to exit WcfTest client...");
Console.ReadLine();
}
private static bool PingFoo(Contracts.Enums.Protocol protocol)
{
FooProxy pxy = new FooProxy(protocol);
return PingProxy<IFooService>(pxy, protocol);
}
private static bool PingStreaming(Contracts.Enums.Protocol protocol)
{
StreamingProxy pxy = new StreamingProxy(protocol);
return PingProxy<IStreamingService>(pxy, protocol);
}
private static bool PingProxy<T>(ProxyServiceBase<T> pxy, Contracts.Enums.Protocol protocol) where T : IServiceBase
{
bool success = pxy.Ping();
Console.WriteLine("ping {0} {1}: {2}", pxy.GetType().Name, protocol, success ? " success" : " FAILED");
if (pxy != null)
pxy.Close();
return success;
}
Any ideas why this would be failing on one IIS site, under one of two protocols, and not on another? (It is not this.)
EDIT: In preparation for taking this bounty-side, a couple clarifications on this test service and client:
First, per commenter's suggestion, svcutil works fine against http, but fails against net.tcp. Here is the complete output of that run:
C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin>svcutil
net.tcp://localhost:9931/StreamingService.svc Microsoft (R) Service
Model Metadata Tool [Microsoft (R) Windows (R) Communication
Foundation, Version 3.0.4506.2152] Copyright (c) Microsoft
Corporation. All rights reserved.
Attempting to download metadata from
'net.tcp://localhost:9931/StreamingService.svc' using WS-Metadata
Exchange. This UR L does not support DISCO. Microsoft (R) Service
Model Metadata Tool [Microsoft (R) Windows (R) Communication
Foundation, Version 3.0.4506.2152] Copyright (c) Microsoft
Corporation. All rights reserved.
Error: Cannot obtain Metadata from
net.tcp://localhost:9931/StreamingService.svc
If this is a Windows (R) Communication Foundation service to which you
have access, please check that you have enabled m etadata publishing
at the specified address. For help enabling metadata publishing,
please refer to the MSDN documentat ion at
http://go.microsoft.com/fwlink/?LinkId=65455.
WS-Metadata Exchange Error
URI: net.tcp://localhost:9931/StreamingService.svc
Metadata contains a reference that cannot be resolved: 'net.tcp://localhost:9931/StreamingService.svc'.
The socket connection was aborted. This could be caused by an error processing your message or a receive timeout bei ng exceeded by
the remote host, or an underlying network resource issue. Local socket
timeout was '00:04:59.9929993'.
An existing connection was forcibly closed by the remote host
If you would like more help, type "svcutil /?"
Second, removing "transferMode="Streamed" from the Wcf.Bindings.Streaming.Tcp web and app configs pasted above allows the service to ping just fine. It does not improve the svcutil situation.
Finally, here are some other things I have tried, with no improvement:
Various versions of serviceMetadata attribute in serviceBehaviors (which I understand to be overridden by the existence of mex endpoints anyway)
Various named serviceBehaviors instead of the default I include
Various configurations of security mode= on the binding, especially None
Various disablings of all other bindings, endpoints, etc. in hopes that one thing might be getting in another's way
It seems that transferMode of tcp communication either at service side or client side to Streamed and the other side still uses the default mode which is Buffered.
Are you forgetting something in "StreamingProxy" in case of TCP?
May be this will help...
http://social.msdn.microsoft.com/Forums/vstudio/en-US/37e32166-63f3-4cb9-ab81-14caa50cd91e/help-with-error-message-the-net-framing-mode-being-used-is-not-supported-by-?forum=wcf
Also I am trying looking further for your solution...

Make Wcf Service IntegratedWindowsAuthentication

I m getting the following error when I did set the Windows Authentication enable and anonymous to disabled in IIS.
The authentication schemes configured on the host
('IntegratedWindowsAuthentication') do not allow those configured on
the binding 'BasicHttpBinding' ('Anonymous'). Please ensure that the
SecurityMode is set to Transport or TransportCredentialOnly.
Additionally, this may be resolved by changing the authentication
schemes for this application through the IIS management tool, through
the ServiceHost.Authentication.AuthenticationSchemes property, in the
application configuration file at the
element, by updating the ClientCredentialType property on the
binding, or by adjusting the AuthenticationScheme property on the
HttpTransportBindingElement.
My Wcf Service's web.config is as follows...
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5"/>
</system.web>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpEndpointBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint binding="basicHttpBinding"
bindingConfiguration="BasicHttpEndpointBinding"
contract="Test.IService1" name="BasicHttpEndpoint" />
</client>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceAuthenticationManager
authenticationSchemes="IntegratedWindowsAuthentication"/>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="false"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpBinding" scheme="http" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
Please advice..
In .Net 4.0+, Simplified WCF configuration uses the 'anonymous' configurations when configurations are not explicitly set on a per-services basis in the <services> section. If you remove the name="BasicHttpEndpointBinding" from the <binding> element, or if you duplicate that <binding> element as a new element with no name attribute, it will become the default, anonymous binding that your WCF services will use. This is often useful in cases where you need to serve as well as consume WCF services that may not all have the same config - but at least you can set a default config for the services that do not have a specific config set. The default/anonymous concept is also applicable to <behavior> elements.
<bindings>
<basicHttpBinding>
<binding> <!--Notice, no name attribute set-->
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" />
</security>
</binding>
</basicHttpBinding>
</bindings>
Also, I might add that if your WCF services require authentication, this means that you will either need to consume the service using a real user account, or you will need to grant the the DOMAIN\CLIENTCOMPUTERNAME$ account access to the service - so, perhaps the proper solution for many people may be to alter the configuration to instead allow anonymous access (which is not discussed in my answer). Still, I do sometimes actually elect to secure my WCF services with Windows (Kerberos) authentication.
Adding this worked for me.
<bindings>
<webHttpBinding>
<binding>
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" />
</security>
</binding>
</webHttpBinding>
</bindings>
I got this error when updating from .NET 4.0 to .NET 4.5.2. I changed the clientCredentialType from
<security mode="TransportCredentialOnly">
<transport clientCredentialType="None"/>
</security>
to
<security mode="TransportCredentialOnly">
<transport clientCredentialType="InheritedFromHost"/>
</security>
However, setting clientCredentialType="Windows" works equally well.
I had the same issue when consuming already existing WCF web URL.
I tried all the answers mentioned here , but all in all finally only two things helped.
Changing the setting in "Turn windows Features on and off".
Enabling Anonymous authentication along with Windows Authentication in Local IIS server.
<services>
<service name="Test.Service1" behaviorConfiguration="TestName">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="BasicHttpEndpointBinding" contract="Test.IService1" />
</service>
</services>
It solved my problem.
Like the other answers, I needed to update the binding in my Web.config to this:
<basicHttpBinding>
<binding name="basicHttpBindin1">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" />
</security>
</binding>
</basicHttpBinding>
But I also needed to update my binding's instantiation:
var binding = new BasicHttpBinding { MaxReceivedMessageSize = 1000000, ReaderQuotas = { MaxDepth = 200 } };
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
binding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;
I had add a webHttpBinding and point my endpoint to that, which the security settings needed to work. Without that my endpoint used the default WCF config bindings:
<services>
<service behaviorConfiguration="ServiceBehavior" name="Service">
<endpoint address="" binding="webHttpBinding" contract="IService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<bindings>
<webHttpBinding>
<binding>
<!--Notice, no name attribute set-->
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" />
</security>
</binding>
</webHttpBinding>
</bindings>
I'm not entirely sure why, but when I added the 'Factory' attribute to my .SVC file (you need to explicitly drag it to Visual Studio), everything just works - without any changes to default settings in Web.config!
I added Factory="System.ServiceModel.Activation.WebServiceHostFactory" so my .SVC file went from this:
<%# ServiceHost Language="C#" Debug="true" Service="ServiceNameSpace.ServiceName" CodeBehind="ServiceName.svc.cs" %>
to this:
<%# ServiceHost Language="C#" Debug="true" Service="ServiceNameSpace.ServiceName" CodeBehind="ServiceName.svc.cs" Factory="System.ServiceModel.Activation.WebServiceHostFactory" %>
The only side effect seems to be that when you click on the .SVC file in the browser, you get an 'Endpoint not found' error, but the service works fine when you invoke it correctly anyway. As mentioned previously, I'm using a default Web.config with .NET 4.6 (Simplified WCF configuration), so I may yet need to add endpoint details for that to work again.

Which IIS settings i have to use for using own password validation with WCF

I've created a simple WCF Service which is hosted in IIS. Now i want to use my own userName authentication.
My web.config:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="MyBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Basic"></transport>
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="WcfIIsBasicAuthTest.Service1" behaviorConfiguration="MyBehavior">
<endpoint address=""
binding="basicHttpBinding"
contract="WcfIIsBasicAuthTest.IService1"
bindingConfiguration="MyBinding"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MyBehavior">
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WcfIIsBasicAuthTest.MyValidator, WcfIIsBasicAuthTest"/>
</serviceCredentials>
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
The Validator
namespace WcfIIsBasicAuthTest
{
public class MyValidator :UserNamePasswordValidator
{
public override void Validate(string userName, string password)
{
if(!(userName == "test" && password == "test"))
{
throw new SecurityTokenException("Validation Failed!");
}
}
}
}
If i start this WCF Service from within visual studio, i get the following error: The authentication schemes configured on the host ('Ntlm, Anonymous') do not allow those configured on the binding 'BasicHttpBinding' ('Basic').
If i try to connect to the service if it is hosted in IIS, i get error messages depending on which authentication type is set, but it doesn't work at all.
Error if only Anonymous authentication is enabled: The authentication schemes configured on the host ('Anonymous') do not allow those configured on the binding 'BasicHttpBinding' ('Basic').
If i set Basic Authentication in IIS, it demands a valid local user which i don't want to provide(since i want to write my own userprovider).
Any hints/links how to setup such a basic auth userprovider with wcf and iis?
Can you set the below configuration for using your own UserNameValidator:
<security mode="TransportWithMessageCredential">
<message clientCredentialType="UserName"/>
</security>
For that to work with basicHttpBinding you would need to have HTTPS setup as WCF doesnt allow username password being passed over the channel in clear text. The other alternative is to use wsHttpBinding.

Categories

Resources