Introduction
Security is a general concern with web services because SOAP (request and response) messages are exchanged (between web service and client) in a plain text format. Though with WSE 2.0/3.0 and WCF, it is very much possible to encrypt the sensitive information in the message, it is a commonly accepted practice to use SSL (HTTPS) communication.
This article discusses the problems that generally pop-up when a SSL enabled (self-signed/test certificate) service is consumed by a .NET application.
Background
To implement SSL on your web service, you need to get and install a certificate issued by a Certificate Authority (CA) on your web server (IIS). Mostly this certificate is used only in production environments. When it comes to development and test environments, a self-signed certificate (test certificate) is being used. You can generate a test certificate using MakeCert.exe tool (included in the .NET Framework SDK) or using (IIS) 6.0 Resource Kit Tools.
Problem #1
When you try to access an SSL enabled web service from your C# code, you will get the following error....
"The underlying connection was closed: Could not establish trust relationship
with remote server."
This is true with a test (self-signed) certificate or a certificate issues by CA where the host name and the name on which the certificate was issued don't match - Perhaps you might be accessing it through an external IP address.
Root Cause of Problem #1
How many times have you observed the following windows in your browsers when browsing an HTTPS web page or a web service?
Internet Explorer 8 displays the following message:
Firefox 3.0.10 displays the following message:
Google Chrome displays the following message:
All the three browsers (Internet Explorer 8, Firefox 3.0.11 and Chome) are asking the user to choose between closing the window or adding an exception because they couldn't verify that this certificate is being issued from a valid CA.
Solution to Problem #1
When you are accessing the web service through your C# code, you should do the same as what you have done in the browser - Trust the certificate!!. But there is no message window for you to accept it when you are accessing it programmatically. So you just need to simulate the message windows and ask it to trust the certificate.
Here is code to simulate the message window.
Add the following code just before invoking a web service method:
ServicePointManager.ServerCertificateValidationCallback
= delegate(Object obj, X509Certificate certificate, X509Chain
chain, SslPolicyErrors errors)
return (true); };
Problem #2
Sometimes even after implementing Solution #1, you might get the following error:
Server was unable to process request. ---> Unable to generate a temporary
class (result=1).
error CS2001: Source file 'C:\WINDOWS\TEMP\zezde3bz.0.cs' could not be found
error CS2008: No inputs specified
Root Cause of Problem #2
Two different settings can cause this problem:
- ASPNET and IUSR users in your system do not have read/write access to 'C:\WINDOWS\TEMP\.
- Your work station is in a different network domain and its WORKGORUP is different. Trust me on this!! In corporate environments where we work in multiple domains (clients and our employers), it is very much possible that you are logging into the system with your employer domain login credentials and your IP address is in your client domain.
Solution to Problem #2
Needless to say, the solution is straight forward:
- The permission problem can be caused by an improper .NET Framework installation. You can re-install the framework or you can just add permissions to ASPNET and IUSR users on 'C:\WINDOWS\TEMP\.
- In the second case, what worked for me is either you should use a local login and your work station is not in any workgroup or your workstation is in the same workgroup as that of its network domain.
History
- 11th July, 2009: Initial post