WCF - Disabling security in nettcpbinding (c#) - c#

I'm trying to make a self hosted WCF app that uses nettcpbinding but works in an environment without a domain.
It's just two regular windows pc's, one is the server and the other one will be the client. The problem with this is that when I try to get the client to connect it's rejected because of the security settings.
Can you please point me in the right direction as to how I can get this scenario to work?
Should I (if possible) disable security?
Is there another (hopefully simple) way to accomplish this?
Regards,
Daniel

If you'd like to disable security for testing purposes, in the App.config of the WCF project, change the security element to <security mode="None" />, e.g.:
<bindings>
<netTcpBinding>
<binding name="netTcpBindingConfig" transferMode="Buffered" maxReceivedMessageSize="5242880">
<readerQuotas maxArrayLength="5242880" />
<security mode="None" />
</binding>
</netTcpBinding>
</bindings>
If you have a client, update the service reference to sync the security settings. Keep in mind that you should use some level of security in production environments.

Related

Enabling SSL for my WCF application is having problems

we have developed a WCF webservice and it has been working fine without any requirement of SSL being introduced. Now, before deploying it to Test envirnment we need to make it SSL enabled.
So I came across this link on SO : Enable SSL for my WCF service
and changed my config file to include following code:
<binding name="BasicHttpBinding_IPromotionalSponsorship" allowCookies="true"
maxReceivedMessageSize="20000000"
maxBufferSize="20000000"
maxBufferPoolSize="20000000">
<readerQuotas maxDepth="32"
maxArrayLength="200000000"
maxStringContentLength="200000000"/>
<security mode="Transport">
</security>
</binding>
While my endpoint looks like following
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IPromotionalSponsorship"
name="StandardEndpoint" contract="PL.Commercial.PromoSponsor.Service.Contracts.IPromotionalSponsorship" />
But it does not sound like it changed anything still when I run my project, it shows the URL without https.
Now, when i explicitly add 's' in the URl it throws following error:
Unable to make a secure connection to the server. This may be a
problem with the server, or it may be requiring a client
authentication certificate that you don't have.
I have created a self-signed certificate and added it to my local IIS. Anything special that I need to change/add?
You need to do following changes.
If you don't need client authentication and just HTTPS then your binding configuration should look like below. Note transport element.
<binding name="BasicHttpBinding_IPromotionalSponsorship" allowCookies="true"
maxReceivedMessageSize="20000000"
maxBufferSize="20000000"
maxBufferPoolSize="20000000">
<readerQuotas maxDepth="32"
maxArrayLength="200000000"
maxStringContentLength="200000000"/>
<security mode="Transport">
<transport clientCredentialType="None"/>
</security>
</binding>
If you want browser to display https when you browse service. Your service behaviour should look like below.
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpsGetEnabled="True" httpsGetBinding="mexHttpsBinding"/>
</behavior>
</serviceBehaviors>
</behaviors>
If you are getting error "Unable to make a secure connection to the server..." as mentioned in question that means you have configured service in such way that it requires client certificate. I guess you just need to enable HTTPS. In that case you don't need to configure client certificate requirement in IIS.
Your application's SSL settings should look like this.

WCF service call returns '407 Proxy Authentication Required'

I am hosting a WCF webservice (on Azure) and have shipped a WPF desktop application to a client who (obviously) tries accessing the service through a proxy.
The service calls fails, returning
The remote server returned an unexpected response: 407 Proxy
Authentication Required
The ServiceModel section of the client app.config file looks like this:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_ILicensing" closeTimeout="00:00:15" openTimeout="00:00:15"
receiveTimeout="00:00:15" sendTimeout="00:00:15" maxReceivedMessageSize="2147483647"
maxBufferSize="2147483647">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
maxArrayLength="2147483647" maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647"/>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="xxxxxxx"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ILicensing"
contract="Cloud.ILicensing" name="BasicHttpBinding_ILicensing" />
</client>
</system.serviceModel>
That's basically all I know.
I would know like to fix this behavior by modifying the app.config file and/or the web.config file of the service (which shouldn't matter, as the service is not reached anyways).
As far as I have understood, there is the attribute useDefaultWebProxy of the binding node, which asks to look up the system proxy configuration and use this for connecting to the service. However, as the default value is true, I would expect that setting it to true explicitly doesn't change anything (that's basically the definition of a default, I guess).
What can be reasons for the failing proxy authentication, considering useDefaultWebProxy is not set and therefor should be true due to it's default value?
How can the app.config be modified in order to fix the issue considering the limitied information? Basically: What do I need to know/ask my client (i.e. proxy server address) and where do I need to insert the information in my client config file?
How can I set up a test environment on my local machine which mimics the issue?
For 1 and 2, you need to configure System.Net to provide default credentials for the default proxy - it doesn't do this by default (because hidden callback code in apps with automatic access to the internet would be bad).
<system.net>
<defaultProxy useDefaultCredentials="true" />
</system.net>
For 3, I'm not entirely sure how you would be able to test this locally as you need a machine to act as the proxy and these are typically domain controller type machines. You could simulate with 2 VMs but I hope you have a powerful machine in order to do so plus it seems like a lot of effort to test this.
You can do it from code
WebRequest.DefaultWebProxy.Credentials = CredentialCache.DefaultNetworkCredentials;

maintaining user session on WCF Clients while making calls to servers behind a load balance

My problem is the following:
- I have a .Net MVC site making a lot of calls to WCF services hosted in two server behind a load balancing server (BIGip).
I do have to maintain a user session on the WCF services (controlled by a custom token).
My problem is that the sticky session is not working when a lot of users is logged on the site (a lot of concurrent calls to the services).
What I figured out was that when the site calls the service reusing a existing connection, the load balancing server ignores the sticky session cookie and forwards the request to the last server that received a call by this connection.
I checked using sniffer (Wireshark), and every call is sent to the load balancing server with the correct sticky session token.
When a connection is created from scratch the stick session cookie is taken into account and the request goes to the right server.
So, how can I handle that situation?
I'm looking for something that enforces creating a new connection on each call, but the property KeepAliveEnabled="false" is not working.
Tks.
My problem was solve using the correct keepAliveConnection configuration to Framework 4.
Bellow are the configs.
The wrong one
<bindings>
<customBinding>
<binding name="WSHttpBinding_IServiceSessionCreator" keepAliveEnabled="false">
<httpTransport />
</binding>
</customBinding>
</bindings>
The correct one
<bindings>
<customBinding>
<binding name="WSHttpBinding_IServiceSessionCreator" >
<textMessageEncoding />
<httpTransport allowCookies="false" keepAliveEnabled="false"/>
</binding>
</customBinding>
</bindings>
I don't know why the first one did not work.
I saw it in this link http://msdn.microsoft.com/en-us/library/vstudio/ms730128(v=vs.100).aspx

WCF Streaming with authentication

I have a WCF service which must be secured with Windows and Certificate authentication.
I know that wsHttpBinding does no support Streaming but according to msdn it can be done using transport security with a customBinding but I am not able to do it...
<customBinding>
<binding name="AuthBinding">
<mtomMessageEncoding maxBufferSize="65535" />
<windowsStreamSecurity protectionLevel="Sign"/>
<httpTransport transferMode="Streamed" maxReceivedMessageSize="2147483647" />
</binding>
</customBinding>
I am going from one exception to another :
The security capabilities of binding 'System.ServiceModel.Channels.CustomBinding' do not match those of the generated runtime object. Most likely this means the binding contains a StreamSecurityBindingElement, but lacks a TransportBindingElement that supports Stream Security
Or
The request message must be protected. This is required by an operation of the contract ('IEntity','WebService.Entity'). The protection must be provided by the binding ('CustomBinding','WebService.Entity')
Rather than being done in a single step, this is two step process.
Enable Transport Security with Certificate Authentication.
Enable Transport Security with Windows Authentication.
Also I am not sure both works together.
But MSDN Article found seems to direct in a correct direction:
How to: Secure a Service with Windows Credentials with wsHttpBinding
Please refer these links from MSDN for further learning (not much help if you are in hurry to deliver some milestone):
Transport Security with Windows Authentication
Transport Security with Certificate Authentication
Update
You have to use custom binding having Mixed (transport with message credentials) security mode.
Three binding elements relate to message level security, all of which derive from the SecurityBindingElement class.
The three are TransportSecurityBindingElement, SymmetricSecurityBindingElement, and AsymmetricSecurityBindingElement. The TransportSecurityBindingElement is used to provide Mixed mode security. The other two elements are used when the message layer provides security.
Additional classes are used when transport level security is provided:
HttpsTransportBindingElement
SslStreamSecurityBindingElement
WindowsStreamSecurityBindingElement
You can get help on:
How to: Create a Custom Binding Using the SecurityBindingElement
and
Security Capabilities with Custom Bindings
This works for me:
<basicHttpBinding>
<binding name="basic" transferMode="Streamed" messageEncoding="Mtom">
<security mode="TransportWithMessageCredential">
<message clientCredentialType="UserName" />
</security>
</binding>
</basicHttpBinding>

WCF sessions with HTTPS

I cannot figure out how to enable per-session instances for my WCF service while using HTTPS. (I'm not an ASP.NET expert but don't want to use ASP.NET session state if possible.) I am using .NET Framework 3.0.
I have arrived at the following contradiction and am hoping that someone can tell me where there is a flaw in the logic.
1) The service must be hosted on IIS 6 due to client mandate.
2) The service needs to maintain state between calls, including SqlConnection and SqlTransaction instances (ugly but necessary due to project constraints).
3) Therefore I need to use the wsHttpBinding.
4) The service needs to be able to access user authentication info from HttpContext.Current.User.Identity (e.g. using Windows security in IIS).
5) HTTPS is therefore required.
6) Transport-level security must therefore be configured on the binding.
7) Configuring the service to require sessions means I have to configure the wsHttpBinding to use Reliable Sessions.
8) This requires that message-level security is configured on the binding.
I.e. (6) and (8) are mutually exclusive.
It seems that using WCF sessions requires that I use message-level security, which prevents me from using HTTPS.
What am I missing?
3) True, wsHttpBinding and wsDualHttpBinding are the only HTTP bindings that support sessions
5) False, in order to authenticate the service callers you don't necessarily need to have any transport-level security (such as SSL/HTTPS). The only requirement is to configure IIS to enable Integrated Windows Authentication for a virtual directory. Then in WCF you have three possibilities to enable this scenario:
a) Use transport-level security on the wsHttpBinding with Windows credentials (HTTPS)
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="SecurityEnabledWsHttp">
<security mode="Transport">
<transport clientCredentialType="Windows" />
</security>
</binding>
</wsHttpBinding>
</bindings>
</system.serviceModel>
b) Use message-level security on the wsHttpBinding with Windows credentials (HTTP)
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="SecurityEnabledWsHttp">
<security mode="Message">
<message clientCredentialType="Windows" />
</security>
</binding>
</wsHttpBinding>
</bindings>
</system.serviceModel>
c) Run your service under the ASP.NET Compatibility Mode and enable Windows Authentication in ASP.NET (HTTP)
<system.web>
<authentication mode="Windows" />
</system.web>
Note that in a and b you will access the identity of the caller from within a service this way:
OperationContext.Current.ServiceSecurityContext.WindowsIdentity
6) True, transport-level security must be enabled on the wsHttpBinding in order to use HTTPS
7) False, Reliable Sessions is a particular implementation of Reliable Messaging for WCF sessions. Reliable Messaging is a WS-* standard specification designed to guarantee message delivery on an unreliable network. You can use WCF sessions without Reliable Messaging, and viceversa. Sessions are enabled on the service contract with this attribute:
[ServiceContract(SessionMode=SessionMode.Required)]
public interface IMyService {
// ...
}
Also remember that in order to maintain state between service calls you will explicitly have to enable the appropriate instance mode on the service contract implementation:
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]
public class MyService : IMyService {
// ...
}
There are two kinds of sessions in WCF: Secure Sessions and Reliable Sessions. The default setting for both wsHttpBinding and netTcpBinding is to use Secure Sessions.For wsHttpBinding this is accomplished with message-level security by using the client's credentials, which is the default setting for the binding.For netTcpBinding instead, the session is established at the tranport level by using the facilities of the TCP protocol.
This means that simply switching to wsHttpBinding or netTcpBinding will enable support for WCF sessions.
The alternative is to use Reliable Sessions. This has to explicitly be enabled in the binding configuration, and removes the requirement of using message security for the wsHttpBinding. So this will work:
<bindings>
<wshttpbinding>
<binding name="ReliableSessionEnabled">
<reliablesession enabled="True" ordered="False" />
<security mode="None" />
</binding>
</wshttpbinding>
</bindings>
8) False, Reliable Sessions are used independently of the security settings of the communication channel.
For a more detailed explanation, have a look at this article.
Following through on Enrico's excellent answer, these are the configs I am using:
Service:
<services>
<service name="Foo.Bar.Service">
<endpoint name="EndpointHttps"
address=""
binding="customBinding" bindingConfiguration="EndpointHttps"
contract="Foo.Bar.IService" />
</service>
</services>
<bindings>
<customBinding>
<binding name="EndpointHttps">
<reliableSession />
<mtomMessageEncoding />
<httpsTransport />
</binding>
</customBinding>
</bindings>
Client:
<client>
<endpoint name="EndpointHttps"
address="https://server/FooBar/service.svc"
binding="customBinding" bindingConfiguration="EndpointHttps"
contract="Foo.Bar.IService" />
</client>
<bindings>
<customBinding>
<binding name="EndpointHttps">
<reliableSession />
<mtomMessageEncoding />
<httpsTransport />
</binding>
</customBinding>
</bindings>
Note: still haven't gotten this to work with Windows authentication though.

Categories