title: Can't override server certificate validation in an Azure Web App
body: <h1>Overview</h1>
  
  <p>I seem to have a variant of the problem listed in <a href="https://stackoverflow.com/questions/34437473/could-not-create-ssl-tls-secure-channel-in-an-azure-web-application?rq=1">this post</a>. However, the answers there don't really help me, and my situation is different.</p>
  
  <p>I'm working for a large corporate, who have decided to trust themselves as a root certificate authority. I've developed a web application, that needs to link to an API hosted in a VM in Azure. </p>
  
  <h2>My Approach</h2>
  
  <p>As I can't install the certificate in the trusted store, I was trying to do this by code. I'm using ASP.NET Web API v2, and I've added the following code to the startup section:</p>
  
  <pre><code>    public void Configuration(IAppBuilder app)
      {
          ConfigureAuth(app);
          var options = CorsOptions.AllowAll;
          app.UseCors(options);
  
          // Override certificate check
          ServicePointManager.ServerCertificateValidationCallback =   MyRemoteCertificateValidationCallback;
      }
  </code></pre>
  
  <p>My callback looks like this:</p>
  
  <pre><code>public bool MyRemoteCertificateValidationCallback(
          object sender,
          X509Certificate certificate,
          X509Chain chain,
          SslPolicyErrors sslPolicyErrors)
      {
          switch (sslPolicyErrors)
          {
              case SslPolicyErrors.RemoteCertificateChainErrors:                    
                  return IsTheCertificateOriginAcceptable(chain);
              case SslPolicyErrors.None:
                  return true;
              default:
                  return false;
          }
      }
  </code></pre>
  
  <p>The certificate origin acceptable function is checking to see if the problem was due to an Unknown Root, and then to see if the unkown root is an extra one the code knows about (because I can't add trusted roots to the Azure Web App - if I had a VM installing the certificate would be the way to go). </p>
  
  <p>If not, it throws a web exception:</p>
  
  <pre><code>bool IsTheCertificateOriginAcceptable(X509Chain chain)
  {
     // checks to see if the initail problem is an untrusted root,
     // and to extract the origin certificate
     if (certificate.IssuerName.Name == expectedIsserName)
     {
         return true;
     }
     else
     {
         throw new WebException($"Certificate origin unacceptable Actual Issue Name '{certificate.IssuerName.Name}', expected issuer name '{expectedIssuerName}'");
     }
  </code></pre>
  
  <p>The plan is to find the issuer name from the VM, and then put that into the code - this is exploratory code, to work out how to get the connection done.</p>
  
  <h2>Running locally</h2>
  
  <p>I then set myself up with IIS with two websites. One running this code, and one on a differnt port, with the default self-signed certificate running a trivial mock of the API I am trying to call. </p>
  
  <p>When I do that, if I don't use the above code, I get the same error I get on Azure:</p>
  
  <pre><code>The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.
  at System.Net.HttpWebRequest.GetRequestStream(TransportContext&amp; context)
  at System.Net.HttpWebRequest.GetRequestStream()
  </code></pre>
  
  <p>If I do use the code, I get the following message</p>
  
  <pre><code>Certificate origin unacceptable Actual Issue Name 'CN=localhost', expected issuer name ''
  </code></pre>
  
  <h2>In the Azure Web App</h2>
  
  <p>When I deploy the above code to Azure, I always get the certificate trust error, which suggests that the callback isn't getting called. </p>
  
  <p>I can't check the SSL settings of the remote server easily, as it isn't connected to the internet (I've connected my azure web app to the VNET the VM is hosted on). </p>
  
  <p>So given all that, how can I connect, other than suggesting that the remote server gets a proper certificate from a known and trusted RCA?</p>