WCF Service client problem - wcf

I'm trying to create a client for a WCF service that I have hosted on IIS 5.1.I'm getting a strange problem: I can access the service through a browser just fine, I see the "You have created a service" page, but whenever I try running svcutil (as suggested by the same page)
svcutil.exe http://my.host.name/SampleService/SampleService.svc?wsdl
I get the following error:
Error: Cannot obtain Metadata from http://localhost.ms.com/SampleService/SampleS
ervice.svc?wsdl
If this is a Windows (R) Communication Foundation service to which you have acce
ss, please check that you have enabled metadata publishing at the specified addr
ess. 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: http://localhost.ms.com/SampleService/SampleService.svc?wsdl
Metadata contains a reference that cannot be resolved: 'http://localhost.ms.
com/SampleService/SampleService.svc?wsdl'.
The HTTP request is unauthorized with client authentication scheme 'Anonymou
s'. The authentication header received from the server was 'Negotiate'.
The remote server returned an error: (401) Unauthorized.
HTTP GET Error
URI: http://localhost.ms.com/SampleService/SampleService.svc?wsdl
There was an error downloading 'http://localhost.ms.com/SampleService/Sample
Service.svc?wsdl'.
The request failed with an empty response.
If you would like more help, type "svcutil /?"
What could be causing this problem?
EDIT: Could it be a problem with IIS itself? Incorrectly set permissions for example?
EDIT: Here's my web.config:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="Basic">
<security mode="None"/>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="DummyService2.SampleService"
behaviorConfiguration="DummyService2.SampleServiceBehavior">
<!-- Service Endpoints -->
<endpoint address="" binding="basicHttpBinding" contract="DummyService2.ISampleService"
bindingConfiguration="Basic" />
<endpoint address="mex" binding="basicHttpBinding" contract="IMetadataExchange"
bindingConfiguration="Basic" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="DummyService2.SampleServiceBehavior">
<!-- 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>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>

I think that this is the relevant error:
The HTTP request is unauthorized with client authentication scheme 'Anonymous'.
The authentication header received from the server was 'Negotiate'.
Is the web service password protected or using integrated Windows authentication? If I remember correctly, svcutil can't log on with integrated authentication to a web service. When you use a browser it works just fine, becuase it handles the authentication in the background for intranet environments.
One option is to download and save the wsdl manually and then point svcutil to use the downloaded wsdl file to generate the classes. You probably have to download some files that are referenced by the wsdl too and edit the references.

Related

WCF Service hosted in IIS 7 using basicHttpBinding and TransportCredentialOnly fails

I am trying to configure a basic IIS 7 hosted WCF service that uses Windows Authentication to authorize users. I have seen many examples that demonstrate how to flow credentials using basicHttpBinding with <security mode="TransportCredentialOnly"> and SSL. When I configure my service to use TransportCredentialOnly, I get the following error if I try to view the svc file in IE:
Could not find a base address that matches scheme http for the
endpoint with binding BasicHttpBinding. Registered base address
schemes are [https].
I am hosting in IIS 7. SSL is configured with a valid certificate. Windows Authentication is on. Anonymous authentication is off. Application pool is ASP.Net v4.0 running under the ApplicationPoolIdentity
Here is the config file for my service:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
<authentication mode="Windows" />
<roleManager enabled="true" defaultProvider="AspNetWindowsTokenRoleProvider">
</roleManager>
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="svcTest" >
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" httpsHelpPageEnabled="true" httpHelpPageEnabled="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpEndpointBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="WCF_Test.Service1" behaviorConfiguration="svcTest">
<endpoint name ="Service1Endpoint"
address="EndpointTest"
binding="basicHttpBinding"
bindingConfiguration="BasicHttpEndpointBinding"
contract="WCF_Test.IService1">
</endpoint>
</service>
</services>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
If I change the binding to use Transport instead of TransportCredentialOnly then I am able to view my service file in IE. I can then create a proxy to my web client and call a method on the service from my client and attempt to authorize the user from the service method using this code:
if(System.Web.Security.Roles.IsUserInRole(#"Admins"))
This code does not work because it uses the identity of the account running IIS on the server (IIS APPPOOL\ASP.NET v4.0) and not that of the user calling the web service from a web page.
How do I configure IIS 7 with a valid SSL certificate to use basicHttpBinding with security mode="TransportCredentialOnly"?
How do I flow my users Windows credentials client to the web service so I can authorize users on the web service using this code?
[PrincipalPermission(SecurityAction.Demand, Role = "Admins")]
or this code
if(System.Web.Security.Roles.IsUserInRole(#"Admins"))
Any help would be greatly appreciated.
Thank You
Probably the problem is in the configuration of IIS, before it gets to your code or your web.config.
If IIS has anonymous authentication turned on, the request coming into ASP.net will look like it came from the user identity of IIS.
In the IIS config you must turn off anonymous authentication and turn on windows authentication.
My guess is you need to use the basicHttp s Binding instead.

Getting Error in Endpoint While Running A WCF REST Service

I'm developing a REST service using WebHttpBinding.
Everything is perfect in my service, but while running it gives Error Endpoint not Found.
The web.config File is like this:
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0"/>
</system.web>
<system.serviceModel>
<services>
<service name="Service">
<endpoint address="http://localhost:10492/Service.svc" binding="webHttpBinding" contract="IService" behaviorConfiguration="webby"/>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="webby">
<webHttp helpEnabled="true"/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the value below to false 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="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<!--
To browse web app root directory during debugging, set the value below to true.
Set to false before deployment to avoid disclosing web app folder information.
-->
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
In address I tried like this also:
<endpoint address="" binding="webHttpBinding" contract="IService" behaviorConfiguration="webby"/>
But it's still not working.
Here is a good link to get you started: http://weblogs.asp.net/kiyoshi/archive/2008/10/08/wcf-using-webhttpbinding-for-rest-services.aspx
On what address are you attempting to connect to your web service? (Have you tried navigating to the address in your web browser, and what URL did you type in?)
[EDIT]
Being that you are hosting in a web application, IIS (or whatever web server you are using) will expect that a service descriptor file exists for your service. You cannot just create a URI in the web.config, and host it in IIS without an associated 'service' file on the file-system (this is your Service1.svc file).
This is a nuance specific to hosting WCF services within Internet Information Services - it is easy to forget about this step, if you are reading tutorials designed for self-hosted scenarios.
Make sure that you have a file in your website called "Service1.svc" and it should contain something like this:
<%#ServiceHost Language="C#" Service="MyNamespace.Service1" Factory="System.ServiceModel.Activation.WebServiceHostFactory" %>
Here is a tutorial on hosting REST services within IIS: http://saravananarumugam.wordpress.com/2011/03/04/simple-rest-implementation-with-webhttpbinding/
Another concern that jumps out at me, is that your endpoint address you have defined ("http://localhost:10492/Service.svc") does not conform to REST conventions. I wouldnt expect this would be your problem, but it is A problem.

WCF service is unavailable after app pool recycles

I'm working on a website that consumes a WCF service hosted in a different app pool, and every time the WCF service's app pool recycles I get a 503 when I'm using the website:
[WebException: The remote server returned an error: (503) Server Unavailable.]
System.Net.HttpWebRequest.GetResponse() +6440728
System.ServiceModel.Channels.HttpChannelRequest.WaitForReply(TimeSpan timeout) +55
[ServerTooBusyException: The HTTP service located at http://cr.genesis.dev/Genesis/RepositoryService.svc is unavailable. This could be because the service is too busy or because no endpoint was found listening at the specified address. Please ensure that the address is correct and try accessing the service again later.]
...
When I try to access the service directly in my web browser it gives me a 503 the first time, but then it works after that (presumably it's causing the application to start?) I'm wondering why the website isn't waking up the web service - even if I try loading a page several times I still get a 503...
I'm using Windsor WCF Integration if that makes any difference, using LifestylePerWebRequest for my client and LifestylePerThread for my service.
This is my config for the service:
<system.serviceModel>
<services>
<service name="Genesis.Repository.Service.RepositoryService" behaviorConfiguration="repositoryServiceBehaviour">
<host>
<baseAddresses>
<add baseAddress="http://cr.genesis.dev/Genesis/" />
</baseAddresses>
</host>
<endpoint name="basicHttpBinding"
address="RepositoryService.svc"
binding="basicHttpBinding"
contract="Genesis.Repository.Service.IRepositoryService" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="repositoryServiceBehaviour">
<!-- 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="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true" />
</system.serviceModel>
And the client:
<system.serviceModel>
<client>
<endpoint name="basicHttpBinding"
address="http://cr.genesis.dev/Genesis/RepositoryService.svc"
binding="basicHttpBinding"
contract="Genesis.Repository.Service.IRepositoryService" />
</client>
</system.serviceModel>
Any suggestions would be appreciated!
Looks like I was making it more complicated than it needed to be - I'd been getting exceptions saying it couldn't listen on http://+:80 which is why I'd played around with netsh permissions and made it listen on /Genesis.
Turns out I can just make it listen on / and specify .Hosted() when registering it with Windsor to tell it to let IIS host it (which is exactly how it was before I installed the WcfFacility!)
Lesson learned, sometimes you just have to go back to basics and things will work as intended!
If you found the "(503) Server Unavailable error" then first point of check is that server is running or not. For this go to the IIS and check the web site is on or off.

Problem with WCF and SSL

I am having problems getting a web service working using SSL and WCF.
If I check in IIS the "Require SSL" seeting then I get this error:
WebHost failed to process a request.
Sender Information:
System.ServiceModel.ServiceHostingEnvironment+HostingManager/36097441
Exception: System.ServiceModel.ServiceActivationException: The service
'/' cannot be activated due to an exception during compilation. The
exception message is: Service
'ISS.MS.WebServices.MessageDispatch.MessageDispatchWebService' has
zero application (non-infrastructure) endpoints. This might be because
no configuration file was found for your application, or because no
service element matching the service name could be found in the
configuration file, or because no endpoints were defined in the
service element.. ---> System.InvalidOperationException: Service
'ISS.MS.WebServices.MessageDispatch.MessageDispatchWebService' has
zero application (non-infrastructure) endpoints. This might be because
no configuration file was found for your application, or because no
service element matching the service name could be found in the
configuration file, or because no endpoints were defined in the
service element.
However if I uncheck it, the page loads fine in the browser but then I get this error
when I try calling it.
Service 'ISS.MS.WebServices.MessageDispatch.MessageDispatchWebService'
has zero application (non-infrastructure) endpoints. This might be
because no configuration file was found for your application, or
because no service element matching the service name could be found in
the configuration file, or because no endpoints were defined in the
service element.
This is the configuration:
<system.serviceModel>
<services>
<service name="ISS.MS.WebServices.MessageDispatchWcfService">
<endpoint
address=""
binding="basicHttpBinding" bindingConfiguration="basicHttpBinding_MS2"
contract="ISS.MS.WebServices.IMessageDispatchWcfService" />
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceDebug includeExceptionDetailInFaults="False" />
<serviceMetadata httpsGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="basicHttpBinding_MS2" >
<readerQuotas maxStringContentLength="1048576" />
<security mode="Transport">
</security>
</binding>
</basicHttpBinding>
</bindings>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true">
</serviceHostingEnvironment>
</system.serviceModel>
I can get it working perfectly using normal HTTP, but HTTPs doesn't work.
I am guessing its either an IIS setting or WCF configuration issue?
I figured it out, the name of the service and contract was not correct...how embarrassing.
Anyone know why it would still work over HTTP even it these are incorrect?
(About "multipleSiteBindingsEnabled"): To enable multiple IIS bindings per site for a service, set this property to true. Notice that multiple site binding is supported only for the HTTP protocol.
ref: http://msdn.microsoft.com/en-us/library/system.servicemodel.configuration.servicehostingenvironmentsection.multiplesitebindingsenabled.aspx
try this
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="false">
</serviceHostingEnvironment>

WCF + IIS6 + HTTPS + Basic authentication

I have seen loads of questions about this, I've spent over a day researching and trying to fix it but I've drawn a blank.
I want to deploy a WCF service onto a server connecting with HTTPS and using basic authentication. Here is my service web.config
I am using an extremely simple Calculator as a test which has a single method which adds together two numbers.
<configuration>
<system.web>
<compilation debug="false" targetFramework="4.0" />
<customErrors mode="Off" />
</system.web>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="UsernameWithTransport">
<security mode="Transport">
<transport clientCredentialType="Basic" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="Service">
<endpoint address="https://myserver.mydomain.co.uk/CalculatorService"
binding="wsHttpBinding"
bindingConfiguration="UsernameWithTransport"
name="BasicEndpoint"
contract="TestCalculator" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
In IIS 6.0 I have enabled basic authentication and required HTTPS.
I can browse to the .svc file and it asks for my credentials. I provide them and it displays the default page. However it says:
You have created a service.
To test this service, you will need to create a client and use it to
call the service. You can do this using the svcutil.exe tool from the
command line with the following syntax:
svcutil.exe
http://myserver.mydomain.co.uk/CalculatorService/Service.svc?wsdl
This will generate a configuration file and a code file that contains
the client class. Add the two files to your client application and use
the generated client class to call the Service. For example: ......
Basically, the issue seems to be that the path to the .wsdl is a http:// not an https:// and I don't think I understand why.
I am now trying to create a C# console application to test consuming the service. I cannot add the reference to the .svc path directly because it just goes around and around in a loop asking me for my username and password. If I add the reference to the .svc?wsdl then that did work but then invoking the service gives a "Method not allowed" because it is trying to use HTTP not HTTPS.
Hope I have expained this well enough. Thanks for any help.
You requires HTTPS but in the same time you allow WSDL only over HTTP. Change this:
<serviceMetadata httpGetEnabled="true"/>
To this:
<serviceMetadata httpsGetEnabled="true"/>
Now you will be able to access WSDL over https://..../....svc?wsdl but you will still have to authenticate because authentication is global for your deployed site.