How secure is WCF wsHttpBinding's Windows authentication?
I have created WCF and I have used wsHttpBinding and MTOM as message transport with authentcation as "Windows".
Now my service is not current SECURE, its plain HTTP, running on custom port.
Is Windows Authentication of WCF's wsHttpBinding secure? can anyone see the password or guess through network trace?
Environment Information:
- Hosted on Internet
- No Active Directory, its single server
- Connecting from my office with server's admin username and password
- On the client side, Password is not mentioned in config file, it is entered at runtime. It works correctly becausing entering wrong credentials returns some sort of security exception as well.
- Running .NET 4.0, on custom port 89, currently I have set following configuration in app.config of my custom windows service, I am hosting my WCF inside custom windows service installed as Local Service. I have enabled impersonation on each method.
Here is the app.config
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="metaAndErrors">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
<serviceAuthorization impersonateCallerForAllOperations="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="CustomServiceHost.CustomService"
behaviorConfiguration="metaAndErrors"
>
<endpoint address="" binding="wsHttpBinding"
bindingConfiguration="wsHttpLargeBinding"
contract="CustomServiceHost.ICustomService"/>
<endpoint address="mex" binding="mexHttpBinding"
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:89/CustomService" />
</baseAddresses>
</host>
</service>
</services>
<bindings>
<wsHttpBinding>
<binding
name="wsHttpLargeBinding" messageEncoding="Mtom"
maxReceivedMessageSize="2147483647">
<readerQuotas maxArrayLength="512000"/>
</binding>
</wsHttpBinding>
</bindings>
</system.serviceModel>
Following is client configuration done at runtime,
WSHttpBinding binding = new WSHttpBinding();
binding.Security.Message.ClientCredentialType
= MessageCredentialType.Windows;
binding.Security.Mode = SecurityMode.Message;
binding.MessageEncoding = WSMessageEncoding.Mtom;
binding.ReaderQuotas.MaxArrayLength = 512000;
CustomServiceClient cc = new CustomServiceClient(
binding,
new EndpointAddress(string.Format(
"http://{0}:89/CustomService",
host.ServerHost))
);
cc.ClientCredentials.Windows.AllowedImpersonationLevel
= System.Security.Principal.TokenImpersonationLevel.Impersonation;
cc.ClientCredentials.Windows.ClientCredential
= new NetworkCredential(host.Username, host.Password);
Thank you,开发者_StackOverflow中文版 - Akash
Regarding your question about the passwords: Windows Authentication either uses Kerberos or NTLM and neither protocol transfers passwords in clear text.
This information is written here: http://msdn.microsoft.com/en-us/library/ff647076.aspx
You should use Integrated Windows authentication instead of basic authentication because it avoids transmitting user credentials over the network.
This means you do not need SSL to protect your passwords, but if you have other information that is sensitive (in your service calls) then you should consider to use encryption (e.g. SSL). I did not try this, but it should get you started:
http://www.codeproject.com/KB/WCF/WCFSSL.aspx
Another option would be to encrypt the messages (message security instead of transport security). Here is another link that should get you started:
http://msdn.microsoft.com/en-us/library/ms733137.aspx
First of all I could not find under <binding>
a child element
<security mode="Message">
<message clientCredentialType="Windows" />
</security>
You should insert it in web.config
(or App.config
). It will corresponds to the currently used message security mode used on the client side.
Moreover a little strange I find that you don't host the WCF service under IIS server. Usage custom windows service installed as Local Service is really not the best choice for a sucure solution. Is it your final configuaration or do you plan to host it at the end under IIS? If it is an opened question I could post you some links where advantages and disadvantages of different hosting ways are described. Are there some important requirements to have WCF service running under LocalSystem
account? Could you shortly describe what the WCF service do? I have problem to give you recommendation to makes too much restriction on the server side which could make the main work of WCF impossible. On the other side to have follow least privilege prinzip to recieve more secure solution.
It is not yet the final answer, only the first remarks.
UPDATED: Hello! Now I have time to end my answer. First of all I want confirm that like Stefan Egli (see another answer) I am sure, that passwords will not send as a clear texts. I am only not sure how exactly Windows authentication works it you have no Active Directory. Probably it works as NTLM authentication with the local server accounts. The small problem is only if you use this NTLM you could not be sure on the client side, that you works really with your WCF server. In such cases the usage of certificate are very helpful.
One way, which suggested also Stefan Egli in his answer, is SSL. It not only makes data encryption, but also authenticate server with the SSL certificate. If you choose the way you should change to message mode to TransportWithMessageCredential.
If the client computer from which you made a remote administration is not a free unmanaged client and you are able to install some components on the machine I'll strongly recommend you to use certificate based authentication and encryption of data (see http://www.codeproject.com/KB/WCF/9StepsWCF.aspx) and install corresponding certificates on both server and client sides. This way is the most secure and after the implementation you will receive both client and server authentication and encryption.
Under http://www.codeproject.com/KB/WCF/9StepsWCF.aspx you will find step by step information how to create and use client and server certificates in WCF. I want only to mention, that one can use MakeCert.exe utility from Windows SDK not only to create a self-signed certificates, but also to create a small PKI. Here is an example:
With
MakeCert.exe -pe -ss MY -a sha1 -cy authority -len 4096 -e 12/31/2020 -r
-n "CN=My Company Root Authority,O=My Company,C=DE" MyCompany.cer
you create a "root" "Self-Signed"-Certificate and save if in MY (personal) certificate store (alternative with respect of -sv switch you can save the private key in a PVK file). You export it also to MyCompany.cer (but without a private key) to make it easier to install it on the client and server computers in Truster Root. Then you can create two other certificates: one for the server and other for a client authentication using root certificate to sign this two certificates. You can do absolutely the same things as in case of having Certificate Server (certificate services) like http://www.codeproject.com/KB/WCF/wcf_certificates.aspx
See for example http://blogs.microsoft.co.il/blogs/applisec/archive/2008/04/08/creating-x-509-certificates-using-makecert-exe.aspx for additional examples.
Other links are important http://msdn.microsoft.com/en-us/library/cc949011.aspx, "How-to Articles" from http://msdn.microsoft.com/en-us/library/ff648902.aspx and http://msdn.microsoft.com/en-us/library/ff650794.aspx can be helpful for you. The article http://msdn.microsoft.com/en-us/library/ms789011.aspx how to make some things in client code (like you do currently).
精彩评论