Wcf custom userNamePasswordValidationMode doesn't work at IIS express - wcf

I tried to make a secure wcf with custom userNamePasswordValidationMode service but I confronted some problems(for three days). My setup environment is visual studio 2012, .net 4.0, IIS Express. My service model in host is:
<system.serviceModel>
<bindings >
<wsHttpBinding>
<binding maxReceivedMessageSize="65536" name="WsHttpBinding_ISurveyService">
<security mode="TransportWithMessageCredential">
<message clientCredentialType="UserName"/>
</security>
<readerQuotas maxArrayLength="65536"
maxBytesPerRead="65536"
maxStringContentLength="65536"/>
</binding>
</wsHttpBinding>
</bindings>
<services>
<!--name= "namespace.serviceClass"-->
<service name="Rids.Services.SurveyService" behaviorConfiguration="Rids.WcfHost.ServiceBehavior" >
<!--contract= "namespace.serviceClass"-->
<endpoint address=""
binding="wsHttpBinding"
bindingConfiguration="WsHttpBinding_ISurveyService"
contract= "Rids.Services.ISurveyService">
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
<host>
<baseAddresses>
<add baseAddress="https://localhost" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="Rids.WcfHost.ServiceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="false" />
<serviceDebug httpHelpPageEnabled="true" includeExceptionDetailInFaults="true" />
<serviceCredentials>
<clientCertificate>
<authentication certificateValidationMode="None" />
</clientCertificate>
<userNameAuthentication userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="Rids.WcfHost.ServiceUserValidator,Rids.WcfHost"/>
<!--Specify the Certificate-->
<serviceCertificate findValue="rids_2014.04.15"
storeLocation="LocalMachine"
x509FindType="FindBySubjectName"
storeName="My"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
When I want to add this service to client, it can not read the metadata and gave the error below:
There was an error downloading 'https://localhost:44300/SurveyService.svc/_vti_bin/ListData.svc/$metadata'.
Unable to connect to the remote server
Hedef makine etkin olarak reddettiğinden bağlantı kurulamadı 127.0.0.1:44300
Metadata contains a reference that cannot be resolved: 'https://localhost:44300/SurveyService.svc'.
There was no endpoint listening at https://localhost:44300/SurveyService.svc that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.
Unable to connect to the remote server
Hedef makine etkin olarak reddettiğinden bağlantı kurulamadı 127.0.0.1:44300
If the service is defined in the current solution, try building the solution and adding the service reference again.
--
But if I delete name tag from behavior(name="Rids.WcfHost.ServiceBehavior" part) and behaviorConfiguration tag from service (behaviorConfiguration="Rids.WcfHost.ServiceBehavior" part); then I can add the service(https://localhost:44300/SurveyService.svc) to client without error. Also this doesn't solve my problem.
After adding service to client, client service model was like below:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_ISurveyService" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:11067/SurveyService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ISurveyService"
contract="Survey.ISurveyService" name="BasicHttpBinding_ISurveyService" />
</client>
</system.serviceModel>
The problems I saw is:
Client service model sees basicHttpBinding although my service binding configuration is wsHttpBinding.
Client service model doesn't see ssl address although I added the service in the path: https://localhost:44300/SurveyService.svc.
I can not add the service to client if service has the behaviorConfiguration tag and behavior has name tag in host configuration.
Custom userNamePasswordValidationMode doesn't work and even if I add service to client without error, service doesn't see validation class or validation method. It works without validation.
Note: Service host project property of 'SSL Enabled' is True; and in project configuration project url is set to https://localhost:44300/.
I've encountered problems in problems. Any advice or solution? Thanks in advance.

I learned how to solve this problem. I made it using EditWcfConfiguration tool in visual studio 2012 as explained below.
Firstly, set property of 'SSL Enabled' as true in host project properties. Under this property automatically ssl url will be generated(such as 'https://localhost:44300/') Then, right click host project and select properties. In project properties Web tab, check 'Use Local IIS Web server' then check 'Use IIS Express'
--
In host project WebConfig, right click then select EditWcfConfiguration:
In EditWcfConfiguration firstly add service, then add a binding for endpoint of service, then add a behavior for service.
1- Add Service
Browse service type at host's bin folder
Select communication mode as HTTP
Select Advanced Web Service interoperability as Simplex communication
Leave the address blank
After adding behavior configuration; select BehaviorConfiguration
After adding binding configuration; open end point of service then, select binding(customBinding) and bindingConfiguration
2- Add a custom binding
Rename binding to use in service's BehaviorConfiguration property (such as 'custom_binding').
Add security, httpsTransport tags.
Select 'AuthenticationMode' as 'UserNameOverTransport' under security tag.
3- In Advanced/Service Behaviors folder, add new service behavior configuration
Rename behavior to use in service end point's BindingConfiguration property (such as safe_behavior).
Add serviceCredentials, serviceMetadata, serviceDebug tags.
For serviceCredentials tag properties:
a-) Select customUserNamePasswordValidatorType as your validator class and its namespace (such as: 'Rids.WcfHost.ServiceUserValidator, Rids.WcfHost')
b-) Select userNamePasswordValidationMode as custom
For clientCertificate tag(under serviceCredentials tag) properties, select certificateValidationMode as None and revocationMode as NoCheck
For serviceMetadata tag properties set HttpsGetEnabled as True
For serviceDebug tag properties set includeExceptionDetailInFaults as True
After these steps, resulting service model is:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="safe_behavior">
<serviceCredentials>
<clientCertificate>
<authentication certificateValidationMode="None" revocationMode="NoCheck" />
</clientCertificate>
<userNameAuthentication userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="Rids.WcfHost.ServiceUserValidator, Rids.WcfHost" />
</serviceCredentials>
<serviceMetadata httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<customBinding>
<binding name="custom_binding">
<security authenticationMode="UserNameOverTransport" />
<httpsTransport />
</binding>
</customBinding>
</bindings>
<services>
<service behaviorConfiguration="safe_behavior" name="Rids.Services.Services.SurveyService">
<endpoint address="" binding="customBinding"
bindingConfiguration="custom_binding" contract="Rids.Services.Services.ISurveyService" />
</service>
</services>
</system.serviceModel>

Related

wsHttpBinding (with https and aspNetCompatibilityEnabled for routing) metadata error 302

I am working on a WCF service which runs along with ASP.NET MVC 2 application with https port which have been configured using webMatrix-ssl certificate. The service is running perfectly in the browser and could download wsdl as well. But when am trying to load the service into wcftestclient tool and as well as my own client, getting the below error.
Error: Cannot obtain Metadata from 'localhost:44300/MyService' If this is a Windows (R) Communication Foundation service to which you have access, please check that you have enabled metadata publishing at the specified address. For help enabling metadata publishing, please refer to the MSDN documentation at go.microsoft.com/fwlink/?LinkId=65455.WS-Metadata Exchange Error URI: localhost:44300/MyService Metadata contains a reference that cannot be resolved: 'localhost:44300/MyService'. The remote server returned an unexpected response: (302) Found. Too many automatic redirections were attempted.HTTP GET Error URI: localhost:44300/MyService There was an error downloading 'localhost:44300/MyService'. The request failed with the error message:--"
I had added the attribute aspNetCompatibilityEnabled="true" for wcf service routing, if that attribute has been removed all works fine. Initially this service has been configured with basicHttpBinding & had this same issue. After reading this article, I have changed to wshttpBinding as suspected binding could also be the problem, still am getting the same issue, below is my web.config.
Could anyone of you please help me to repair this?
<system.serviceModel>
<extensions>
<behaviorExtensions>
<add name="ExceptionBehavior" type="ServiceExceptionHander.ExceptionHandlerBehaviorExtension, ServiceExceptionHandler" />
</behaviorExtensions>
</extensions>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true" />
<ExceptionBehavior />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="ServiceImplementation.MyService" behaviorConfiguration="ServiceBehavior">
<endpoint binding="wsHttpBinding" bindingConfiguration="securityBinding" contract="ServiceContracts.IMyServiceContracts"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="securityBinding">
<security mode="Transport">
<transport clientCredentialType="None"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true">
<serviceActivations>
<add factory="System.ServiceModel.Activation.ServiceHostFactory" service="ServiceImplementation.MyService" relativeAddress="MyService.svc"/>
</serviceActivations>
</serviceHostingEnvironment>
</system.serviceModel>

Can't host tcp based wcf service on IIS, Cannot obtain Metadata from net.tcp://localhost/TestApp2/MyService error pops up

I have a simple test purpose WCF service. I'm trying to host it under IIS 7.5 ( Windows 7 ) but no luck so far. I'm getting error
Cannot obtain Metadata from net.tcp://localhost/TestApp2/MyService
I have a web site TestApp2 under Default Web Site, I enabled tcp on Default Web Site and TestApp2. Here is my web.config file, while I realize that this error simply states that I didn't have endpoint for metadata exchange, I can't see what's the problem because I included endpoint for metadata exchange.
<system.serviceModel>
<services>
<service behaviorConfiguration="ServiceBehavior" name="MyService">
<endpoint address="net.tcp://localhost/TestApp2/MyService"
binding="netTcpBinding"
bindingConfiguration="PortSharingBinding"
contract="II7WcfService.IService1" />
<endpoint address="MEX"
binding="mexTcpBinding"
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost/TestApp2/MyService" />
</baseAddresses>
</host>
</service>
</services>
<bindings>
<netTcpBinding>
<binding name="PortSharingBinding" portSharingEnabled="true">
<security mode="None"/>
</binding>
</netTcpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="False" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
Thanks.
My guess is your service isn't actually called MyService but rather it is in a namespace. This means your declared endpoints are not getting picked up, and the default ones (which doesn't include IMetadataExchange) are being used instead.
Add the name of your namespace to the attribute in the config and it should work.

basicHttpBinding security mode not successfully inferred by wcf test client

I have a WCF Service programmed in VB.NET that is exhibiting strange behavior. The web.config has the following xml:
<system.serviceModel>
<services>
<service behaviorConfiguration="CentricBasicHttpBehavior" name="OnbaseService">
<endpoint binding="basicHttpBinding" bindingConfiguration="CentRicBasicHttpServerBinding" contract="IOnbaseService">
<identity>
<servicePrincipalName value="HTTP/JFOLKENDT7E" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="CentricBasicHttpBehavior">
<serviceAuthorization impersonateCallerForAllOperations="true" />
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<dataContractSerializer maxItemsInObjectGraph="2147483646" />
<serviceThrottling maxConcurrentCalls="100" maxConcurrentSessions="100" maxConcurrentInstances="100" />
</behavior>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<bindings>
<basicHttpBinding>
<binding name="CentRicBasicHttpServerBinding" maxReceivedMessageSize="5000000">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" />
</security>
</binding>
</basicHttpBinding>
</bindings>
</system.serviceModel>
When I configure the service in wcf test client, both the Binding Mode and TransportClientCredentialType are coming across as "None". I expected for them to be "TransportCredentialOnly" and "Windows" respectively.
Can someone please share with me how WCF Test Client infers the binding configuration, and how I should go about correcting this issue? The end result is that within the source code of the service, the WindowsIdentity isn't impersonating the user like I expected.
Thanks,
Jason
I work with Jason and we looked at this together. The service configuration needed the name and contact properties to match the fully qualified service class name and fully qualified contact interface name. Otherwise, we were getting the fun new .Net 4.0 defualt bindings for a default service.
In my own experience with WCF, I had modified session Timeouts and connection Timeout settings in the config file but WCF Test Client was not respecting those settings. Seems like WCF Test client just takes up the default values for communicating with WCF services. Hence I test my WCF services using my own custom WCF Test Clients by generating app.config and proxy. cs through svcutil.exe .

Configuration binding extension could not be found

I am trying to get a WCF webservice running which will participate in distributed transactions. I keep getting the following error message...
Configuration binding extension 'system.serviceModel/bindings/myBinding' could not be found. Verify that this binding extension is properly registered in system.serviceModel/extensions/bindingExtensions and that it is spelled correctly
Here is the web.config
<system.serviceModel>
<services>
<service name = "DistServiceX">
<endpoint
address=""
binding="myBinding"
contract="IDistService"
/>
</service>
</services>
<bindings>
<wsHttpBinding>
<binding
name="myBinding"
transactionFlow="true"
/>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
Can anyone see what is wrong with this? It's driving me crazy!
Thanks
Pete
You are referring to a custom binding here:
<service name = "DistServiceX">
<endpoint
address=""
binding="myBinding"
contract="IDistService" />
However, there is no custom binding called myBinding anywhere in your config.
I assume you really want to refer to a wsHttpBinding and the myBinding binding configuration that you specified in your config file. Furthermore: the name of the service must match the fully qualified name of the class that implements the service - including namespace (and also: the name of the contract being implemented by that service and exposed on a given endpoint must include any namespaces):
<service name="YourNamespace.DistServiceX">
<endpoint
address=""
binding="wsHttpBinding"
bindingConfiguration="myBinding"
contract="YourNamespace.IDistService" />

IIS hosted WCF-service + Windows auth in IIS + TransportCredentialOnly/Windows auth in basicHttpBinding

I want to create a WCF-service hosted in IIS6 and disable anonymous authentication in IIS. And don't use SSL.
So only way I have is to use basicHttpBinging with TransportCredentialOnly, itsn't it?
I create a virtual directory, set Windows Integrated Auth and uncheck "Enable Anonymous Access".
Here's my web.config:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="MyBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="Samples.ServiceFacadeService" behaviorConfiguration="ServiceFacadeServiceBehavior">
<endpoint address="" binding="basicHttpBinding" bindingName="MyBinding"
contract="Samples.IServiceFacadeService">
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceFacadeServiceBehavior">
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
You can see that I even haven't included MEX-enpoint for metadata exchange. Just one endpoint and one binding for it with TransportCredentialOnly security.
But when I tries to start service (invoking a method throught client proxy) I got such exception in the EventLog:
Exception:
System.ServiceModel.ServiceActivationException:
The service
'/wcftest/ServiceFacadeService.svc'
cannot be activated due to an
exception during compilation. The
exception message is: Security
settings for this service require
'Anonymous' Authentication but it is
not enabled for the IIS application
that hosts this service.. --->
System.NotSupportedException: Security
settings for this service require
'Anonymous' Authentication but it is
not enabled for the IIS application
that hosts this service.
I have no idea why my service require Anonymous auth? Why?
The answer found jezell. Thanks.
I mixed up bindingName and bindingConfiguration :
<endpoint address="" binding="basicHttpBinding" bindingName="MyBinding"
contract="Samples.IServiceFacadeService">
</endpoint>
That's right:
<endpoint address="" binding="basicHttpBinding" **bindingConfiguration**="MyBinding"
contract="Samples.IServiceFacadeService">
</endpoint>
The MEX endpoint may still be the problem (see this post). Try disabling MEX like this:
<services>
<!-- Note: the service name must match the configuration name for the service implementation. -->
<service name="MyNamespace.MyServiceType" behaviorConfiguration="MyServiceTypeBehaviors" >
<!-- Add the following endpoint. -->
<!-- Note: your service must have an http base address to add this endpoint. -->
<endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceTypeBehaviors" >
<!-- This disables it. -->
<serviceMetadata httpGetEnabled="false" />
</behavior>
</serviceBehaviors>
</behaviors>
Here is a good post on securing MEX.
Use basicHttpBinding for your mex endpoint and apply the same bindingConfiguration:
To get VS wcf service project (new sample project) to work with authentication under IIS, you have to:
1) Allow Anonymous access in IIS
2) Prefix your public methods with a attribute like this:
[PrincipalPermission(SecurityAction.Demand, Role = "MyADGroup")]
public string SendMyMessage(string Message)
{...}