Metadata request requires authentication in WCF even though service description page doesn't - wcf

I've set up a WCF service to require NTLM authentication using the following configuration:
<system.serviceModel>
<bindings>
<customBinding>
<binding name="BinarySecurityBinding">
<binaryMessageEncoding/>
<httpTransport authenticationScheme="Ntlm"/>
</binding>
</customBinding>
</bindings>
<services>
<service name="Services.LogisticsServices" behaviorConfiguration="ServiceBehavior">
<endpoint address="" binding="customBinding" bindingConfiguration="BinarySecurityBinding" contract="Services.ILogisticsServices" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
I did this so that the applications that consume the web service are forced to log in because all my service's operations use impersonation ([OperationBehavior(Impersonation = ImpersonationOption.Required)]).
In IIS 7 I've enabled anonymous and Windows authentication.
When I visit http://test.server/LogisticsServices.svc, which hosts the service described above, I can see the default service description page anonymously. However, when Visual Studio tries to access http://test.server/LogisticsServices.svc/$metadata to generate a client proxy, the server is responding with HTTP code 401 and expecting authentication. Not only would I've expected the metadata to be available anonymously, but additionally, the server is not accepting the credentials I am giving it (even though, I know for a fact that they are correct).
Testing different configuration, I tried removing the authenticationScheme from my binding's transport, just to be able to generate the client proxy, but that results in an exception because the service's operations require impersonation ([OperationBehavior(Impersonation = ImpersonationOption.Required)]).
What am I missing in my service's configuration that would make the service's metadata available anonymously? I'm also open to suggestions if I'm approaching the whole thing wrong.

here is a similar discussion:
Getting an Security setting exception while accessing a WCF service

One way around this is not to use the autogenerated proxies.
In cases where we have control over both the server and the client we have found that it is much more productive to avoid using the autgenerated proxies.
A screencast of how to do this can be found here: http://www.dnrtv.com/default.aspx?showNum=122
You could try imperative instead of declarative model, see: http://msdn.microsoft.com/en-us/library/ms730088.aspx

Related

mvc wcf security

I have a MVC application which uses forms authentication. This application also hosts a WCF webservice (the Model). Webservice caters c# objects to the application, and same data is available as JSON when called from outside the application (browser).
Everything is working fine apart from the fact that the Webservice is not authenticating any request. Following is the what I have in web.config:
<system.serviceModel>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
<behaviors>
<endpointBehaviors>
<behavior name="ServiceBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<webHttpBinding>
<binding name="webHttpBindingWithJson" crossDomainScriptAccessEnabled="true" />
</webHttpBinding>
</bindings>
<services>
<service name="Services.MyService">
<endpoint address="http://localhost:1234/MyService.svc/" binding="webHttpBinding"
bindingConfiguration="webHttpBindingWithJson"
contract="Services.IService"
behaviorConfiguration="ServiceBehavior"/>
</service>
</services>
I would like to authenticate Webservice requests:
Requests from within the application should be authenticated automatically
When Webservice is called from outside the application, users are asked to get authenticated.
Any help would be appreciated.
/D
Sounds like you need an internal endpoint that serves a wsdl for the binding in to the website (authenticated using the ASP.NET identity the website is running under) and a separate binding externally for the JSON requests that uses something like OAuth to authenticate.
Either way you're looking at two different authentication mechanisms.

wsHTTPBinding over HTTPS causes Error 400 'Bad Request'

I've been trying to create a simple service to allow messages to be logged onto a remote server via WCF, which all worked fine until I published the service to the live environment, which uses HTTPS.
After some searching, I found that I needed to change my ServiceConfig to account for the different protocol. I used a combination of these two articles:
How to configure WCF services to work through HTTPS without HTTP binding?
WCF Bindings needed for HTTPS
Having made the recommended changes to my config, I seem to be in a state where I can add the live service as a WCF reference in VS2010, but when I use IE to browse to the service or the mex address, I'm consistently receiving an 'HTTP 400 Bad Request' error.
In terms of using the service I can seem to run it successfully but the mex just doesn't want to work through IE.
The Service itself is being hosted on Windows Server 2003 R2 Standard Edition SP2 Running IIS 6.0 with no load balancing.
I'm really at a loss at this point, I've spent 3-4 days messing around with this but I can't seem to make any progress. So any help would be greatly appreciated.
See below the Server service config in question:
<system.serviceModel>
<services>
<service name="mycorp.Callback.SecPayService" behaviorConfiguration="mycorp.Callback.SecPayServiceBehavior">
<endpoint address="https://myserver.co.uk/SecPay/SecPayService.svc"
binding="wsHttpBinding" bindingConfiguration="TransportBinding"
contract="mycorp.Callback.ISecPayService"/>
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="mycorp.Callback.SecPayServiceBehavior">
<serviceMetadata httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="TransportBinding">
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
</wsHttpBinding>
</bindings>
</system.serviceModel>
If you are hosting your service in IIS then just have the endpoint elements address value to empty string as the address for the endpoint is assigned by IIS

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 Error - Could not find a base address that matches scheme

I'm trying to get a WCF web service to work with SSL, as you can imagine it works on my machine, however when I run it on the production environments I get this instead:
Could not find a base address that matches scheme http for the endpoint with binding BasicHttpBinding. Registered base address schemes are [https].
Despite many hours of wrestling with this problem I still have very little idea what this error message actually means - googling for this error message finds loads of people saying that I should either specify an address in my endpoint configuration or add a base address to my service, however:
My service worked perfectly fine without specifying either with SSL disabled
In fact, my service works perfectly fine with SSL with the exact same configuration on another machine
Besides, I've found a post which reliably informs me that when hosting under IIS the base address is ignored anyway.
As you can probably tell, I'm currently feeling a very fustrated at my utter failure to achieve what I believed to be a relatively simple task, so:
What does this error message actually mean?
How are base addresses determined when hosting under IIS?
Where can I find reliable, understandable documentation about what all of my copy-pasted configuration actually means?
What do I need to do to get my service to actually work?
The interesting bits of my web.config are:
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
<services>
<service name="MyService" behaviorConfiguration="MyBehavior">
<endpoint binding="basicHttpBinding" bindingConfiguration="SecureTransport"
bindingNamespace="http://MyNamespace/Service" name="Basic"
contract="MyContract" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MyBehavior">
<serviceMetadata httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="SecureTransport">
<security mode="Transport" />
</binding>
</basicHttpBinding>
</bindings>
</system.serviceModel>
One thing that is off field but can cause this message is if the SSL certificate on the server is expired or not set up correctly.

SSL WCFs with custom binding

Has anyone ever tried to use custom binding with SSL in a WCF web service? I've seen a number of examples on how to do this with basicHttpBinding and wsHttpBinding but the equivalent always fails for customBinding. Specifically what I'm currently working with (the most successful configuration yet) looks something like this:
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true">
</serviceHostingEnvironment>
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceBehavior">
<serviceMetadata httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<customBinding>
<binding name="binaryHttps">
<binaryMessageEncoding />
<httpsTransport />
</binding>
</customBinding>
</bindings>
<services>
<service behaviorConfiguration="MyServiceBehavior" name="MyService">
<host>
<baseAddresses>
<add baseAddress="https://(myserver)/"/>
</baseAddresses>
</host>
<endpoint address=""
binding="customBinding" bindingConfiguration="binaryHttps"
contract="MyService" />
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
</service>
</services>
</system.serviceModel>
This actually allows us to access the service from the web, get it's WSDL and add a service reference inside visual studio alright, but when we actually try and use it live in our silverlight-3 application, it just sits there indefinitely waiting for a response and never times out. It actually ends up giving me low memory problems after a while on my machine (with 6GB of memory). The odd thing is that all this worked (and still does) perfectly in the development environment (using strictly the VS application hosts), it wasn't until we tried to deploy it to an actual server with a real SSL certificate that all these issues popped up.
I've searched fairly exhaustively for a solution to this problem but have so far not found anything and have tried just about everything - Is there anyone out there that's encountered this before and got around it?
So it turns out the problem wasn't with our web.config at all, it had to do with an issue with IIS 7 and Wildcard SSL certificates.
Namely, IIS 7 doesn't allow you to specify the hostname when binding an IP to an SSL connection and certificate. I'd guess that this is because it expects a non-wildcard SSL certificate that it can extract the explicit hostname from. What we ended up having to do was to go into the applicationHost.config file in {WindowsDir}\{System32}\{Inetsrv}\{config} and find the entry with our web service's bound IP address and change it explicitly to (ip):(hostname). It was then even displayed properly in the IIS config GUI.
After doing this we were to completely turn off all but SSL channels on all our servers and everything worked beautifully.
Thank god that's over!
AFAIK, using SSL has performance problem. We are using WCF behiovr to do the authentication. The way that we are using is that Silverlight => ASP.NET => WCF. We configured the Endpoint behivor in both Silverlight and WCF. Whenever we call the service, we passed the token for authentication.
Are you saying that you can use custom binding in ClientConfig of Silverlight?