Enable SSL for my WCF service - wcf

I have a WCF service that uses basicHttpbinding in development.
Now in product we want to use SSL, what changes do I have to make to force SSL connections only?

This page on MSDN explains WCF Binding Security.
http://msdn.microsoft.com/en-us/library/ms729700.aspx
The BasicHttpBinding class is
primarily used to interoperate with
existing Web services, and many of
those services are hosted by Internet
Information Services (IIS).
Consequently, the transport security
for this binding is designed for
seamless interoperation with IIS
sites. This is done by setting the
security mode to Transport and then
setting the client credential type.
The credential type values correspond
to IIS directory security mechanisms.
The following code shows the mode
being set and the credential type set
to Windows. You can use this
configuration when both client and
server are on the same Windows domain.
C#
BasicHttpBinding b = new BasicHttpBinding();
b.Security.Mode = BasicHttpSecurityMode.Transport ;
b.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
Or, in configuration:
<bindings>
<basicHttpBinding>
<binding name="SecurityByTransport">
<security mode="Transport">
<transport clientCredentialType="Windows" />
</security>
</binding>
</basicHttpBinding>
</bindings>
To enable ssl, without a login, set clientCredentialType to "None".
Options for security mode are:
None, Transport, Message, TransportWithMessageCredential and TransportCredentialOnly
You can find more details at: http://msdn.microsoft.com/en-us/library/system.servicemodel.basichttpsecuritymode.aspx

I just faced the same problem and found this MSDN article:
How to: Configure an IIS-hosted WCF service with SSL
At the end of the article you will find the xml configuration of the WebConfig file.
The solution worked just fine for me. One more thing to say, keep in mind that you need a REAL certificate for your release!

I think that if under your bindings where you have the <Security mode="Transport">, if you would change it to be <security mode="None">, you would be ok.
This is a copy of a code base that I'm working on and I tried that in-code, and it appears to be working.
I get the WSDL at least when I call the service, if that helps at all.
BasicHttpBinding basicBinding = new BasicHttpBinding();
if (RegistryConnectionStringFactory.UseSslForCommunications)
{
basicBinding.Security.Mode = BasicHttpSecurityMode.TransportWithMessageCredential;
basicBinding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;
}
else
{
basicBinding.Security.Mode = BasicHttpSecurityMode.None;
basicBinding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;
}

Related

Does Message Security still work when I set Security Mode to Transport in WCF

I have a WCF service which the security mode has been set to "Transport".
Below is my service configuration:
<bindings>
<netTcpBinding>
<binding name="tcpConSecure" >
<security mode="Transport">
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
</security>
</binding>
</netTcpBinding>
</bindings>
When I use VisualStudio "Edit WCF configuration" tool to open my configuration, in security tab, it will display like this:
Question:
Does the setting in MessageSecurity properties area still work when I set mode to Transport? I ask this question because I didn't set message security related properties in config file.
When I set Security Mode to "Transport" and client credential type to "Windows", will the transfer message between server/client be encrypted? By which algorithm?
From this link, the messages are secured at the transport level by windows security. What does Windows Security mean?
For the first question, if the mode is set to "Transfer", the settings in the MessageSecurity properties area will be invalid. Securing a service with both transport and message credentials uses the best of both Transport and Message security modes in Windows Communication Foundation (WCF). In sum, transport-layer security provides integrity and confidentiality, while message-layer security provides a variety of credentials that are not possible with strict transport security mechanisms. For more information about TransportWithMessageCredential, you can refer to this link.
If the Transport mode is used, the main mechanism used to protect the transmission is the Secure Sockets Layer (SSL) based on HTTP, usually called HTTPS. So if we use Transport mode, we need to bind a certificate to the service. For more information about Transport Security, you can refer to this link.

How to use Message security and UserName clientCredentialType without Certificate in WCF Service?

i have a WCF service with wsHttpBinding which my clients are my windows application and my website. both those clients are consumer of the my service. in the my service, i used a Message security and UserName clientCredentialType for clients authentication. i do not want use any certificate for this authentication. how do i? or you suggest to me other solution for this sake?
WsHttpBinding message security with UserName client creadentials demands server certificate. The only option is to use Windows client credentials but in such case your client and service must be in the same AD domain (or trusted domains). If you want to secure message (encrypt and sign) you need such infrastructure.
Edit:
Based on your comment you don't need message security, you only want to use UserNameToken profile to transport client credentials over insecured channel. This is possible in WCF 4 (and in older versions with special KB). Try this custom binding:
<customBinding>
<binding name="UsernamePasswordOverHttp">
<textMessageEncoding messageVersion="Soap11" />
<security
authenticationMode="UserNameOverTransport"
messageSecurityVersion="WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10"
allowInsecureTransport="true" />
<httpTransport />
</binding>
</customBinding>
Be aware that there can be some problem with autogenerating WSDL for such service.
Edit 2:
Another possibility is to use ClearUserNameBidning.
thanks for your example. i used your example but i received this error:
The Scheme cannot be computed for this binding because this CustomBinding lacks a TransportBindingElement. Every binding must have at least one binding element that derives from TransportBindingElement.
and other my question: for this solution i use from which project type in VS2010? a WCF Service Library in project or a WCF Service website. which one?
thank you for your answers.

Exception during secure communication implementation

im trying to implement simple secured client server communiction using WCF.
when im launching mt server everty thing is OK , But when im launching my client im getting this error:
Error : An error occurred while making the HTTP request to https://localhost:800
0/ExchangeService. This could be due to the fact that the server certificate is
not configured properly with HTTP.SYS in the HTTPS case. This could also be caus
ed by a mismatch of the security binding between the client and the server.
this is the server code :
Uri address = new Uri("https://localhost:8000/ExchangeService");
WSHttpBinding binding = new WSHttpBinding();
//Set Binding Params
binding.Security.Mode = SecurityMode.Transport;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
binding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
Type contract = typeof(ExchangeService.ServiceContract.ITradeService);
ServiceHost host = new ServiceHost(typeof(TradeService));
host.AddServiceEndpoint(contract, binding, address);
host.Open();
this is the client configuration (app.config):
</client>
<bindings>
<wsHttpBinding>
<binding name="TradeWsHttpBinding">
<security mode="Transport">
<transport clientCredentialType="None"
proxyCredentialType ="None"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
the security configuration at both the client and the server are the same , and i dont need certificate for the server in that kind of security (transport) so why do i get
this exception ????
thanks...
Well looking at your code:
Uri address = new Uri("https://localhost:8000/ExchangeService");
You're specifying that the address is using SSL (https) so it would require a certificate for that purpose. Either use a http binding or install a certificate.
I'd check out the Application Scenarios and How Tos section on this CodePlex Link for different configurations and details of how to configure them.

WCF - How to configure netTcpBinding for NTLM authentication?

I know how to configure basicHttpBinding for NTLM authentication, but can't figure out a way to do the same for netTcpBinding.
Does netTcpBinding support NTLM? If so, how to force WCF service to use NTLM?
BTW a well known method using identity element for some reason didn't work at all. I am looking for something like this - clientCredentialType ="Ntlm" but for tcp.
Here is basicHttp setting:
<basicHttpBinding>
<binding name="BasicHttpBinding">
<security mode ="TransportCredentialOnly">
<transport clientCredentialType ="Ntlm"/>
</security>
</binding>
</basicHttpBinding>
Here is the comprehensive answer that I finally found, tested, and confirmed.
A. My WCF client used to build an EndPoint.Address dynamically as follow
EndPointAddress myEdpintAddress = new EndPointAddress(stringURL);
But in the case of a secure transport (net.tcp) it has to be initialized as follow
EndPointAddress myEdpintAddress = new EndPointAddress(new UrRL(string), myEndPointIdentity)
Without the EndPointIdentity parameters the Identity property in the EndPointAddress object is null, and generates the “...target principal name is incorrect... " error on the server side.
B. Our domain controller supports both Kerberos and Ntlm authentication. After above is done, generally there are four configuration scenarios on the client side for the net.tcp binding if security is other than “None”, and the WCF service runs as a domain account:
No <identity> elements in the client endpoint specified - WCF call fails
<identity> element provided, but with an empty value for dns, userPrioncipalName or servicePrincipalName elements - WCF call successful, but uses the Ntlm authentication
<identity> element provided with the a value for dsn or SPN – WCF call successfull; service uses Ntlm to authenticate.
<identity> element provided with the correct value for upn – WCF call successfull; service uses Kerberos for authenticate. Incorrect or missing value for upn trigger Ntlm authentication
Thanks.
The Net TCP Binding does not support "NTLM" as a client credentials type - you have a choice of None, Windows or Certificate only (see the MSDN docs on TcpClientCredentialType).
So in your case, try this:
<netTcpBinding>
<binding name="tcpWindows">
<security mode ="TransportCredentialOnly">
<transport clientCredentialType ="Windows"/>
</security>
</binding>
</netTcpBinding>
Any reason why this doesn't work??

Connecting to a WSE 3.0 Web Service From a WCF Client

I'm having difficulty connecting to a 3rd party WSE 3.0 web service from a WCF client. I have implemented the custom binding class as indicated in this KB article:
http://msdn.microsoft.com/en-us/library/ms734745.aspx
The problem seems to have to do with the security assertion used by the web service - UsernameOverTransport.
When I attempt to call a method, I get the following exception:
System.InvalidOperationException: The
'WseHttpBinding'.'[namespace]'
binding for the
'MyWebServiceSoap'.'[namespace]'
contract is configured with an
authentication mode that requires
transport level integrity and
confidentiality. However the transport
cannot provide integrity and
confidentiality..
It is expecting a username, password, and CN number. In the example code supplied to us by the vendor, these credentials are bundled in a Microsoft.Web.Services3.Security.Tokens.UsernameToken. Here's the example supplied by the vendor:
MyWebServiceWse proxy = new MyWebServiceWse();
UsernameToken token = new UsernameToken("Username", "password", PasswordOption.SendPlainText);
token.Id = "<supplied CN Number>";
proxy.SetClientCredential(token);
proxy.SetPolicy(new Policy(new UsernameOverTransportAssertion(), new RequireActionHeaderAssertion()));
MyObject mo = proxy.MyMethod();
This works fine from a 2.0 app w/ WSE 3.0 installed. Here is a snippet of the code from my WCF client:
EndpointAddress address = new EndpointAddress(new Uri("<web service uri here>"));
WseHttpBinding binding = new WseHttpBinding(); // This is the custom binding I created per the MS KB article
binding.SecurityAssertion = WseSecurityAssertion.UsernameOverTransport;
binding.EstablishSecurityContext = false;
// Not sure about the value of either of these next two
binding.RequireDerivedKeys = true;
binding.MessageProtectionOrder = MessageProtectionOrder.SignBeforeEncrypt;
MembershipServiceSoapClient proxy = new MembershipServiceSoapClient(binding, address);
// This is where I believe the problem lies – I can’t seem to properly setup the security credentials the web service is expecting
proxy.ClientCredentials.UserName.UserName = "username";
proxy.ClientCredentials.UserName.Password = "pwd";
// How do I supply the CN number?
MyObject mo = proxy.MyMethod(); // this throws the exception
I've scoured the web looking for an answer to this question. Some sources get me close (like the MS KB article), but I can't seem to get over the hump. Can someone help me out?
I had success in a similar case with the following binding configuration:
<bindings>
<customBinding>
<binding name="FNCEWS40MTOMBinding">
<security enableUnsecuredResponse="true" authenticationMode="UserNameOverTransport"
allowInsecureTransport="true" messageProtectionOrder="SignBeforeEncrypt">
<secureConversationBootstrap />
</security>
<mtomMessageEncoding messageVersion="Soap12WSAddressingAugust2004"
maxBufferSize="2147483647" />
<httpTransport maxReceivedMessageSize="2147483647" />
</binding>
</customBinding>
</bindings>
Hope it works for you too.
The error message is refering to Transport Level Security, this usually means https.
You have not shown your configuration files. But I am guessing that you have configured security to be transport (or it is required as a consiquence of another choice) and used an address that is http instead of https.