January 29, 2021

Call WCF - Set SecurityProtocol & ServerCertificateValidationCallback

.Net Applications use ServicePointManager.SecurityProtocol Property to specify the version of the Secure Sockets Layer (SSL) or Transport Layer Security (TLS) protocol for new connections, existing connections aren't changed.

It is recommended that you should not specify this property manually and let it be use its default value, which will be obtained from machine configuration. Still In some scenarios, you may want to specifically define the SecurityProtocol when calling a WCF service with Https link. In this case you can define the required protocols like this:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls
                   | SecurityProtocolType.Tls11
                   | SecurityProtocolType.Tls12
                   | SecurityProtocolType.Ssl3;

Since these are flags, so you can use bitwise OR(|) operator to specifiy multiple protocols if your connection requires.

Another property is ServerCertificateValidationCallback, which is used by the client to perform custom validation for the server certificate. The sender parameter passed to the RemoteCertificateValidationCallback can be a host string name or an object derived from WebRequest (HttpWebRequest, for example) depending on the CertificatePolicy property.

If you trust the server and not using custom validation, you can simply return true from the callback method.

 
ServicePointManager.ServerCertificateValidationCallback =
             new RemoteCertificateValidationCallback(IgnoreCertificateErrorHandler);

Here is the definition of IgnoreCertificateErrorHandler, which will always return true.

private static bool IgnoreCertificateErrorHandler(object sender,
   X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{​​​​​​​
	return true;
}​​​​​​​

You can also replace the above callback method definition with a short-hand delegate syntax.

ServicePointManager.ServerCertificateValidationCallback += delegate { return true; };

References:

January 23, 2021

When to set ServicePointManager.SecurityProtocol Property

When communicating with external services using TLS/SSL through APIs (such as HttpClient, HttpWebRequest, FTPClient, SmtpClient, SslStream), .Net application uses ServicePointManager.SecurityProtocol Property as the version of the Secure Sockets Layer (SSL) or Transport Layer Security (TLS) protocol for new connections, existing connections aren't changed.

Summary points

  • No default value is listed for this property for .Net Framework versions prior to 4.6.2.
  • Since default protocols and protection levels are changed over time in order to avoid known weaknesses. Therefore defaults vary depending on individual machine configuration, installed software, and applied patches.
  • When developing custom applications, avoid the assumption that a given security level is used by default. Only if you are sure that a particular application connection requires an specific security level (SSL/TLS) then you can explicitly specify the matching level in your code.

Review the following points for TLS support in different .Net Frameworks.

  • Starting with the .NET Framework 4.7, the default value of this property is SecurityProtocolType.SystemDefault. Which means the default security protocols from the operating system (or from any custom configurations performed by a system administrator) will be inherited by .NET Framework's networking APIs based on SslStream (such as FTP, HTTP, and SMTP).
  • For .NET 4.6 and above: Includes a new security feature that blocks insecure cipher and hashing algorithms for connections. TLS 1.2 is supported by default.
  • For .NET 4.5: TLS 1.2 is supported, but it’s not a default protocol. You need set manually. The following code will make TLS 1.2 default, make sure to execute it before making a connection to secured resource:
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
    
  • For .NET 4.0: TLS 1.2 is not supported, but if you have .NET 4.5 (or above) installed on the system then you still set for TLS 1.2 even if your application framework doesn’t support it. The problem is that SecurityProtocolType in .NET 4.0 doesn’t have an entry for TLS1.2, so you would have to use a numeric value and cast it to SecurityProtocolType enum:
        ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
    
  • For .NET 3.5 or below: TLS 1.2 is not supported. Upgrade your application to more recent version of the framework.

References:

HTTP Error 500.19 - Internal Server Error - HRESULT: 0x8007000d

I added URL rewrite section in web.config file in .Net Core 2.2 Application, and it starts generating the error HTTP Error 500.19 - Internal Server Error.

Error Details:

    Server Error in Application "application name"
    HTTP Error 500.19 – Internal Server Error
    HRESULT: 0x8007000d
    Description of HRESULT
    The requested page cannot be accessed because the related configuration data for the page is invalid.

Cause

As per MSDN:

This problem occurs because the ApplicationHost.config or Web.config file contains a malformed XML element.

Resolution

As per MSDN:

Delete the malformed XML element from the ApplicationHost.config or Web.config file.

But since URL rewrite config section is not malformed as these are all valid config xml. In my case I found that URL rewrite module was not installed on the server, so installing the missing module fixed my issue.

You can download URL Rewrite Extension from Official Microsoft IIS Site:

Or use Direct MSI link for winx64

It should start working at this point.

Install .Net Core Hosting Bundle and reset IIS:

If it still not works, try to install / repair the .Net Core Hosting Bundle. e.g You can download version 6.0 from Download .NET 6.0

Finally, reset IIS by running the following command:

iisreset

You need to open the command prompt with Run as administrator option.

References: