WCF configuration and authentication nightmare - wcf-security

I am working with windows server 2008 r2 running iis 7.5. My WCF service is running on framework 4.0. 32-bit app running integrated pipeline.
Service is in a virtual directory with Annonymous and Windows Authentication enabled. My configuration looks like:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="MyBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="MyWebservice.MyService" behaviorConfiguration="MyWebservice.MyServiceBehavior">
<!-- Service Endpoints -->
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="MyBinding" contract="MyWebservice.IMyService" />
<endpoint address="mex" binding="basicHttpBinding" bindingConfiguration="MyBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MyWebservice.MyServiceBehavior">
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true" />
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
When I connect with the WCF Test Client from an account that is on the domain, I get the following exception:
The HTTP request is unauthorized with client authentication scheme 'Negotiate'. The authentication header received from the server was 'Negotiate'.
This error is profoundly un-helpful. Can anyone point me to the error of my ways?

Reboot fixed the error. When will I ever learn, with Windows... when things stop making sense, reboot.

Related

WCF service call returns empty file / page

The problem:
When I'm calling my deployed WCF service, the browser downloads an empty svc file and does not show me the page with the service xml file.
The context:
I have to move the webapp hosting the WCF service to a new server. This service was working fine on the old server, that was running IIS.
The new server has 2 webservers running. IIS 8.5 and WAMP 2.5, because the server hosts an Php app and Jira.
The setup:
The WAMP server listens to the 80 port and then redirects to IIS, to a specific port, if needed. This is an example for the setup.
Wamp config (https-vhosts.confg):
<VirtualHost *:80>
ServerName site.de
ServerAlias www.site.de
<Proxy *>
Require all granted
</Proxy>
ProxyRequests Off
ProxyPreserveHost On
ProxyPass / http://localhost:9050/
ProxyPassReverse / http://localhost:9050/
The service URL:
https://www.site.de/folder/service.svc
Service config:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="someBinding" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" maxBufferPoolSize="52428899">
<readerQuotas maxDepth="64" maxStringContentLength="81920" maxArrayLength="163840" maxBytesPerRead="40960" maxNameTableCharCount="163840" />
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="LargeServiceBehavior">
<serviceMetadata httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
<useRequestHeadersForMetadataAddress />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true" />
<services>
<service name="ExampleServices.ExampleService" behaviorConfiguration="LargeServiceBehavior">
<endpoint address="http://www.site.de/folder/service.svc"
binding="basicHttpBinding"
bindingConfiguration="someBinding"
contract="ExampleServiceModels.IExampleService" />
</service>
</services>
I have never worked with wamp before. And I don't have much experience with WCF settings also. Any ideas or tips would be highly appreciated.
EDIT
Using the wcf test client i get this:
Error: Cannot obtain Metadata from http://www.site.de/folder/ExampleService.svc 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 http://go.microsoft.com/fwlink/?LinkId=65455.WS-Metadata Exchange Error URI: http://www.site.de/folder/ExampleService.svc Metadata contains a reference that cannot be resolved: 'http://www.site.de/folder/ExampleService.svc'. The requested service, 'http://www.site.de/folder/ExampleService.svc' could not be activated. See the server's diagnostic trace logs for more information.HTTP GET Error URI: http://www.site.de/folder/ExampleService.svc The document at the url http://www.site.de/folder/ExampleService.svc was not recognized as a known document type.The error message from each known type may help you fix the problem:- Report from 'XML Schema' is 'Root element is missing.'.- Report from 'DISCO Document' is 'Root element is missing.'.- Report from 'WSDL Document' is 'There is an error in XML document (0, 0).'. - Root element is missing.
You need to specify a MEX (meta data exchange) binding to expose you WSDL. Example (look at the address "mex"):
<service name="ExampleServices.ExampleService" behaviorConfiguration="LargeServiceBehavior">
<endpoint address="http://www.site.de/folder/service.svc" binding="basicHttpBinding"
bindingConfiguration="someBinding"
contract="ExampleServiceModels.IExampleService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
To get the wsdl type in the browser:
https://www.site.de/folder/service.svc?wsdl
Not sure this answer will help OP after almost 3 years. But it is more intended for #GothamLlianen. But if you want to access a WFC service on a HTTPS connection, you need to specify that binding explicitly.
Add this in the <system.serviceModel> node of the Web.Config
<bindings>
<webHttpBinding>
<binding name="HttpsBinding">
<security mode="Transport">
<transport clientCredentialType="None"/>
</security>
</binding>
</webHttpBinding>
</bindings>
Then add the name, in this case "HttpsBinding" to the endpoint
<endpoint bindingConfiguration="HttpsBinding"
The complete node below for reference
<system.serviceModel>
<services>
<service behaviorConfiguration="ServiceBehaviour" name="MyProject.Api">
<endpoint bindingConfiguration="HttpsBinding" address="" behaviorConfiguration="web" binding="webHttpBinding" contract="MyProject.IApi" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehaviour">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
<serviceAuthorization principalPermissionMode="UseAspNetRoles" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp defaultOutgoingResponseFormat="Json" defaultBodyStyle="Bare" />
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<bindings>
<webHttpBinding>
<binding name="HttpsBinding">
<security mode="Transport">
<transport clientCredentialType="None"/>
</security>
</binding>
</webHttpBinding>
</bindings>
</system.serviceModel>

Problems with WCF Webservice and SSL

I've read lots of threads the last hours but I did not find a solution which is working for me :-(
So as already multiple other users I have problems calling a SVC-Webservice via SSL from my Windows Phone 7 application. On localhost it works fine. I've deployed the Webservice within my Webapplication. The service "MyService.svc" is in the root of the webapplication. On IIS I've only added HTTPS (from Startcom, using default Port 443) for this IP and made SSL required. I could open my web application and I could open the Webservice using any browser at http://mydomain.com/MyService.svc, from both server and local development machine. The page says I could call svcutil.exe https://mydomain.com/MyService.svc?wsdl. When I click on the link the data is display correct.
Now when I try to access it via WP7 app I always get the following error:
"There was no endpoint listening at https://mydomain.com/MyService.svc that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details."
And inner details say: "The remote server returned an error: NotFound."
Here is the important part of my web.config. I don't know whether this is all required, as said I've copied it from multiple threads but at least in IE it works fine:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="MyBehavior">
<serviceMetadata httpsGetEnabled="true" httpGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="true" />
<dataContractSerializer maxItemsInObjectGraph="1073741824" />
<useRequestHeadersForMetadataAddress>
<defaultPorts>
<add scheme="https" port="443" />
</defaultPorts>
</useRequestHeadersForMetadataAddress>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="MyBehavior" name="MyNamespace.MyService">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="HttpsBinding"
contract="MyNamespace.IMyService">
</endpoint>
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange"/>
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="HttpsBinding">
<readerQuotas maxStringContentLength="2147483647" />
<security mode="Transport">
<transport clientCredentialType="None"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<!-- <serviceHostingEnvironment multipleSiteBindingsEnabled="true" /> -->
Many thanks!

Configuration binding extension 'system.serviceModel/bindings/clearUsernameBinding' could not be found

hi i am tring to use this article for making my wcf service authenticate without SSL
http://webservices20.blogspot.in/2008/11/introducing-wcf-clearusernamebinding.html
but i am geting this error when i try to compile :
<system.serviceModel>
<extensions>
<bindingExtensions>
<add name="clearUsernameBinding" type="ClearUsernameCollectionElement, ClearUsernameBinding" />
</bindingExtensions>
</extensions>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="MyValidator,App_Code"/>
</serviceCredentials>
<!--To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment-->
<serviceMetadata httpsGetEnabled="true"/>
<!--To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information-->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
<behavior name="SampleServiceBehaviour">
<serviceMetadata httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="MyUserNameValidator, App_Code" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="Service" behaviorConfiguration="SampleServiceBehaviour">
<endpoint address="~/QuadraService/Service.svc" binding="wsHttpBinding" contract="IService" bindingConfiguration="Binding1"/>
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange"/>
<endpoint binding="clearUsernameBinding" bindingConfiguration="myClearUsernameBinding" contract="IService" />
</service>
</services>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
<bindings>
<clearUsernameBinding>
<binding name="myClearUsernameBinding"
messageVersion="Soap12">
</binding>
</clearUsernameBinding>
<wsHttpBinding>
<binding name="Binding1">
<!-- UsernameToken over Transport Security -->
<security mode="TransportWithMessageCredential" >
<message clientCredentialType="UserName"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
Description: An error occurred during the processing of a configuration file required to service this request. Please review the specific error details below and modify your configuration file appropriately.
Parser Error Message: Configuration binding extension 'system.serviceModel/bindings/clearUsernameBinding' could not be found. Verify that this binding extension is properly registered in system.serviceModel/extensions/bindingExtensions and that it is spelled correctly.
please help
Seems like you are receiving the "An error occurred when verifying security for the message" exception because you have not manually modified the configuration file on the client.
The author states the following in the comments:
As for the desktop application, the client needs to manually configure
clearUsernameBinding as done in the sample console application. The
reason is that the clearUsernameBinding dll is not part of .Net 3.5
and needs to be deployed on the client side.

Unable to Connect to WCF Service from MVC Site

I've written a WCF service that is hosted within a Windows Service on my home computer. I then wrote an MVC3 site that is attempting to connect to the service. The MVC3 site is hosted on godaddy servers. I opened the ports on my firewall correctly because I am able to access the service description site from a computer on a different network, and I even had a friend connect to the web service from a console app running on his computer, and it worked perfectly. However, when I attempt to call the web service from my MVC3 site it throws the following error:
There was no endpoint listening at http://myExternIpAddress:8000/MyService/service that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.
Here is the important part of the app.config for the service:
<services>
<service name="MyService.MyService"
behaviorConfiguration="MyServiceBehavior" >
<host>
<baseAddresses>
<add baseAddress="http://localhost:8000/MyService/service" />
</baseAddresses>
</host>
<endpoint address=""
binding="basicHttpBinding"
contract="MyService.IMyService" />
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
and here is the service section of the web.config for the MVC3 site
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IMyService" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://myExternalIpAddress:8000/MyService/service"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IMyService"
contract="LocalService.IMyService" name="BasicHttpBinding_IMyService" />
</client>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
Thanks for any help that you can provide!
I would contact GoDaddy for support. If the WCF service works from your friends machine - it is likely a hosting environment issue.

Is there a way to pass domain credentials from the originating browser in webHttpBinding wcf service?

Is there a way to pass domain credentials from the originating browser in webHttpBinding WCF service?
I'm thinking this should be possible as when I log into any aspx page with Windows Authentication enabled in IIS, I can get the calling user's domain credentials. How would I setup my WCF service in such a manner? Currently the user identity I get in the WCF service are those of the app pool the svc is running under?
EDIT
I don't have .NET 4 -- My configuration file is below, but I still get an error:
Security settings for this service require 'Anonymous' Authentication
but it is not enabled for the IIS application that hosts this service.
Should I explicitly enable Anonymous for that path in IIS? I think this would undo my efforts to get the domain name.
<behaviors>
<endpointBehaviors>
<behavior name="Awesome.Project.OperationsBehavior">
<enableWebScript />
</behavior>
</endpointBehaviors>
</serviceBehaviors>
<behavior name="Awesome.Project.OperationsServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="Awesome.Project.OperationsServiceBehavior"
name="Awesome.Project.Operations">
<endpoint address="" binding="webHttpBinding"
contract="Awesome.Project.Operations"
behaviorConfiguration="Awesome.Project.OperationsBehavior"
bindingName="windowsSecurityWebHttpBinding">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<!--<endpoint address="mex" binding="mexHttpBinding"
contract="IMetadataExchange" />-->
</service>
</services>
<bindings>
<webHttpBinding>
<binding name="windowsSecurityWebHttpBinding">
<security mode="Transport">
<transport clientCredentialType="Windows"/>
</security>
</binding>
</webHttpBinding>
</bindings>
You need to turn on authentication in the service - assuming .NET 4 add the following to your config
<bindings>
<webHttpBinding>
<binding>
<security mode="Transport">
<transport clientCredentialType="Windows"/>
</security>
</binding>
</webHttpBinding>
</bindings>
for .NET 3.5 or 3.0 you need
<bindings>
<webHttpBinding>
<binding name="webBindingConfig">
<security mode="Transport">
<transport clientCredentialType="Windows"/>
</security>
</binding>
</webHttpBinding>
</bindings>
<services>
<service ...>
<endpoint bindingConfiguration = "webBindingConfig" binding="webHttpBinding" .../>
</service>
</services>
Edit for additional questions:
WCF will generally not pass credentials over non secured transports - that's why mode="Transport" is important. If you got rid of it its the same as Mode="None" for WebHttpBinding
If the site is considered to be in the intranet zone then IE will pass the user's credentials automatically. However, non-IE browsers will not and so will hit the site anonymously before getting a 401 and then sending the credentials. The intial request requires anonymous access to be supported in IIS as WCF handles the authentication mechanism
If you need to get hold of HttpContext you can use Asp.NET Compatibility. However in WCF you can use ServiceSecurityContext.Current.PrimaryIdentity.Name to get the authenticated user
How to: Impersonate the Original Caller in WCF Calling from a Web Application gives a walkthrough on how to do this.

Resources