WCF: myservice.svc?wsdl shows "You have created a service.", not WSDL? - wcf

I've created a WCF service with a wsHttpBinding and a mexHttpBinding. When running on http in IIS6, the myservice.svc shows the usual "You have created a service." page. myservice.svc?wsdl shows XML containing WSDL.
I changed from <security mode="None"> to <security mode="Transport"> and now I try reaching the same service using https. myservice.svc still shows "You have created a service." But myservice.svc?wsdl also shows "You have created a service."
What am I doing wrong?
The service still works (made a client when using http, and changed to https afterwards). But VS cannot generate a new client using https, probably because the ?wsdl page is broken.

In serviceMetadata behavior you must set httpsGetEnabled to true.

Related

Kerberos authentication on a self-hosted WCF Data Service

We have a WCF Data Service which is self-hosted under a Windows service (not using IIS) which we are currently working to secure using SSL and Windows Authentication.
After some time playing around with netsh and server certificates, we now have the service secured with SSL and we have also enabled Windows Authentication on the webHttpBinding in our app.config - however we are now seeing some strange behaviour when attempting to authenticate certain users - some can log in fine, others have their credentials rejected and are prompted with HTTP 400 errors.
After some testing and digging around it would appear that we might be running into this problem, where the authentication header used by Kerberos may be greater than the maximum permitted header length (which I believe is 16k) for certain users - and although there is a documented workaround for IIS, there does not appear to be an equivalent setting we can use for a self-hosted service, or in our app.config - unless I'm missing something? We tried setting the maxReceivedMessageSize and maxBufferSize fields to their maximum values to see if that would make any difference, but apparently not.
Binding config:
<webHttpBinding>
<binding name="DataServicesBinding"
maxReceivedMessageSize="2147483647"
maxBufferSize="2147483647">
<security mode="Transport">
<transport clientCredentialType="Windows" />
</security>
</binding>
</webHttpBinding>
We've managed to work around this issue temporarily by setting the clientCredentialType in our binding to use Ntlm instead, but we'd like to get Kerberos working if possible for obvious reasons.
So, as it turns out, this was caused by our service not being configured with a SPN (Service Principal Name). This can be done using the setspn tool with Windows Server. (See this MSDN article for more information.)
Once the SPN was applied, Kerberos authentication started to work as expected.
Use wireshark to see what the client sends. Make sure that this input is correct and then come back.

WCF SOAP over HTTPS, WCF Test Client calls the http address and the server responds with 404

TL;DR version is at the bottom.
I have constructed three WCF web services -- one that's using .NET 4 and two that's using .NET 3.5 -- that is consumed by an Android client. The Android client performs the calls using ksoap2-android. When the services were complete and the client could make all the calls and get all the data from the services, we decided to activate HTTPS communication for the web services. They are hosted on a server running IIS.
I'm not alone on this task. I work full-time with it, mainly the Android client. I have two coworkers, both of which have a lot of other responsibilities. The first is mostly involved in the services and the second is mostly involved in the server.
I've read a lot of guides, blogs and articles on the Internet on how to enable HTTPS for a WCF web service, but still I haven't been able to completely resolve this. For the Android client to be able to consume the client, we are limited to using the basicHttpBinding, since the wsHttpBinding contains some security details that are not supported by Android, or something. I'm not sure, but I read it some forum somewhere. If I'm wrong, I'd happily be corrected!
Okay, so I'll give a short account of what I've done so far:
I've enabled transport security, this is how the binding(s) looks:
<bindings>
<basicHttpBinding>
<binding name="basicHttp" closeTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00">
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
</basicHttpBinding>
</bindings>
I've enabled meta data publishing over HTTPS using this line of code:
<serviceMetadata httpsGetEnabled="true" />
and this:
<endpoint address="" binding="mexHttpsBinding" contract="IMetadataExchange" />
Also, my second coworker has installed a trusted certificate (a real certificate from a CA) on the IIS server and added a https binding on the server.
Okay, so far, so good. Now we could connect to the services in the browser.
When we had done this it was possible to visit the service in the browser in a secure, encrypted, manner.
The problem is that it isn't possible to make a call to the service, neither in Android nor WCF Test Client. If I call the service on the https address, I get a 404 in response. WCF Test Client returns this:
There was no endpoint listening at https://[my service address] that could accept the message. This is often caused by an incorrect address or SOAP action.
To be able to debug this, I'm using Wireshark to intercept the messages and see what really happens. I've found out that after the set up procedures (handshake, establishing trust etc.) the client sends the header and get a 101 Continue in response, after which it POSTs the body. This should be normal behavior. But then the service returns 404 Not Found. Wireshark says that the full request URI is the http address. I've configured the server to use the https address, so why does it make a call to the http address?
I've tried setting the address and listenUri attribute of the endpoint to https and http respectively and the other way around. If I do that, the server answers the request with 405 Method Not Allowed.
Is there any way to solve this? What am I missing?
What am I missing?
TL;DR version below
I'm hosting three WCF SOAP web services with IIS, one using .NET 4 and the others using .NET 3.5. I'm trying to make a call from the WCF Test Client over HTTPS. I've enabled transport security, meta data publishing over HTTPS, installed a trusted certificate and added a https binding on the server.
When I try to make a call from WCF Test Client it says that there was no endpoint listening at the address. Wireshark tells me it makes the call to the http version of the service (i.e. "http://[my address]" instead of "https://[my address]"), although it is configured to call the https address. The service returns 404 Not Found. If I set the address of the service to https and listenUri to http, I get 405 Method Not Allowed. If I do it the other way around it says that it cannot be activated. What am I missing?
I solved this by removing the endpoint and using the <protocolMapping> tag, like this:
<protocolMapping>
<add scheme="https" binding="basicHttpBinding" bindingConfiguration="basicHttps" />
</protocolMapping>

WsHttpBinding with security mode TransportWithMessageCredential in IIS 7 not working

We are currently migrating a WCF service from IIS 6 to IIS 7. The service contains some non-SSL endpoints for internal streaming purposes and some exposed endpoints secured with SSL.
The public, secure endpoints are implemented using wsHttpBinding and security mode="TransportWithMessageCredential". The binding reads as follows:
<wsHttpBinding>
<binding name="CustomSecurityBinding">
<security mode="TransportWithMessageCredential">
<message clientCredentialType="UserName" />
</security>
</binding>
</wsHttpBinding>
The credentials are authenticated against a custom user repository for validation.
After deploying the service to IIS 7 (64bit Win2k8), all services (basicHttpBindings) respond correctly, expect for the wsHttpBindings. If triggered using https, we always get a HTTP 400 status code (Bad Request).
After enabling tracing in IIS, we could kinda narrow down the problem, although the message from the trace did not really help:
MODULE_SET_RESPONSE_ERROR_STATUS Warning
ModuleName="ManagedPipelineHandler", Notification="EXECUTE_REQUEST_HANDLER",
HttpStatus="400", HttpReason="Bad Request", HttpSubStatus="0", ErrorCode="Der
Vorgang wurde erfolgreich beendet. (0x0)", ConfigExceptionInfo=""
Steps done so far:
re-installed WCF extensions in IIS 7 (ServiceModelReg.exe -r -y)
enabled https protocol for host, added self-signed certificate to host
played around with dns/identity setting in wcf configuration
added a base address to wcf service config
After 2 hours of googling and trying to make this work, i ask you as a last resort of hope: Does anybody know this strange behaviour of IIS 7?
Have you verified that the SSL binding is configured in applicationHost.config (%windir%\system32\inetsrv\config\schema\IIS_Schema.xml) and that the HTTP.sys store contains a valid certificate has and store name for the binding? Secondly, the true error could be masked by the 400 error, have you tried altering your wsHttpBinding in configuration to increase the maxBufferPoolSize and maxReceivedMessageSize to some extremely high values and see if this continues?

Silverlight, WCF service, integrated security AND ssl/https not possible?

I have this setup that works perfectly when using http.
A silverlight 3 client
.net 4 WCF service hosted in IIS with basicHttpBinding and using integrated security on the site
When setting https to required on the website the setup stops working.
Using the wcftestclient on the uri I get the message:
The HTTP request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the server was 'Negotiate,NTLM'. The remote server returned an error: (401) Unauthorized.
Maybe this makes sense because the wcftestclient does not pass credentials?
in the web.config the security mode for the service binding is set is set to 'Transport'.
The silverlight client is created like this:
BasicHttpBinding basicHttpBinding = new BasicHttpBinding();
basicHttpBinding.Security.Mode = BasicHttpSecurityMode.Transport;
var serviceClient = new ImportServiceClient(basicHttpBinding, serviceAddress);
The service address is ofcourse starting with https://
And the silverlight client reports this error:
The provided URI scheme 'https' is invalid; expected 'http'.
Parameter name: via
Remember, switching it back to http (and setting security mode to 'TransportCredentialOnly' makes everything working again.
Is the setup I want even supported? If so, how should it be configured?
Turns out that the above setup does work. The key is
basicHttpBinding.Security.Mode = BasicHttpSecurityMode.Transport;
In de client code, and
<binding name="silverlightBinding" maxReceivedMessageSize="10485760">
<security mode="Transport">
<transport clientCredentialType="Windows"/>
</security>
</binding>
at the service end.
Somehow I was working with a xap file without the changes in the security mode. As soon as I used the newly compiled xap it started working.

IIS Rest over HTTPS only

I've asked a similar question here:
How to enforce one method in WCF Rest to be called via https, while others can be called over http
And it doesn't look like it is possible on the code side. Is it possible to set up an entire service to be callable over HTTPS only? I've configured a service using the following binding:
<webHttpBinding>
<binding name="webBinding"
maxBufferSize="152428800" maxReceivedMessageSize="152428800"
receiveTimeout="00:10:00">
<readerQuotas maxStringContentLength="152428800"
maxArrayLength="152428800"
maxBytesPerRead="4096"/>
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
</webHttpBinding>
But when I try to call a simple service over http, the service returns the result happily, rather than returning some sort of exception. Do I need to configure IIS to only service https requests? Has anyone tried this?
Thanks!
Did you configure IIS to require SSL on your application's folder? (you can set it to allow ssl or make it mandatory)
You can always add an explicit endpoint to your service entry with a fully-qualified https address. Can't remember if IIS hosting always auto-adds the base addresses when you have an explicit address, but even if it does, you can make a simple extension of ServiceHostFactory to "eat" the default base addresses IIS supplies (reference your custom servicehostfactory in the Factory attribute of your .svc file). Then it'll only answer on the exact addresses you supplied in the config.
It's possible via configuration. This Blog Article is not your exact scenario (it's file transfer over https), but it shows sample config and code for configuring and consuming a https web service that should be useful.