2

We have onpremise web service (asp.net core mvc) deployed on local network machine. We are trying to call these WEB API using App Service deployed on Azure. But it is giving time out error or Task was cancelled error in case when we try to connect it using "HTTP" Protocol. In case of "HTTPS" it is giving "security error occurred error".

We have created Hybrid connection on Azure App Service to connect to onpremise web api service which shows online for both 80 and 443 port. We have setup Hybrid Connection Manager on local network machine too.

Below is the code snippet for calling code which is deployed on Azure App Service (e.g. https://xyz.azurewebsite.com)

 try
 {
    var httpClient = new HttpClient();
    httpClient.Timeout = TimeSpan.FromMinutes(60);
    httpClient.BaseAddress = new Uri("https://onpremise");
    httpClient.DefaultRequestHeaders.Accept.Clear();
    httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
    ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
    //Simple Get Request to test on-premise service
    var response = await httpClient.GetStringAsync("api/OnPremiseData/GetData");
    ViewBag.ResponseText = response;
 }

Above code works fine in case I debug application from localhost. So there is no issue with code I assume.

Below is web api code snippet:

[Route("api/[controller]/[action]")]
public class OnPremiseDataController : Controller
{        
  [HttpGet]
  public string GetData()
  {
    return "Success";
  }
}

and below is startup.cs file

public void ConfigureServices(IServiceCollection services)
{
  services.AddCors();
  services.AddMvc();            
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
  app.UseCors(options => options.WithOrigins("https://xyz.azurewebsite.com", "https://localhost:44310").AllowAnyMethod().AllowAnyHeader());
  if (env.IsDevelopment())
  {
    app.UseDeveloperExceptionPage();
  }            
  app.UseMvc();                
}
arpan desai
  • 889
  • 2
  • 13
  • 23

2 Answers2

2

We had similar scenario (WebApp and SQL on-premise) and the trick was to use fully qualified domain name of the endpoint in Hybrid Connection Manager on the on-premise machine.

maciek
  • 521
  • 1
  • 4
  • 18
  • I think I am able to connect to SQL Server just by mentioning endpoint. E.g. tcp:onlyhostname,1433 in connection string. Any idea how to connect rest api in similar way? I need to try out using fully qualified name. Hope it will work. – arpan desai Dec 31 '17 at 05:40
  • Our connection was successful as well, yet requests did not come through until endpoint was FQDN. – maciek Dec 31 '17 at 08:27
  • Yeah. FQDN works for me!! but only for HTTP not for HTTPS. When I use HTTPS it is throwing "A security error occurred". – arpan desai Jan 01 '18 at 06:33
  • I have also used ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls; ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true; – arpan desai Jan 01 '18 at 06:39
  • Ok I have found solution. Providing my answer myself. Thanks a lot for point me out. – arpan desai Jan 01 '18 at 07:08
2

Below is the solution for above question. Basically I have solved 2 problem.

First is using FQDN (fully qualified domain name) I am able to connect to on-premise services. Please make sure you are using FQDN while configuring endpoint in Hybrid connection on Azure.

Second, using below line of code I am able to make secure HTTPS request ot on-premise server:

    HttpMessageHandler handler = new HttpClientHandler
    {
         SslProtocols = System.Security.Authentication.SslProtocols.Tls12 | System.Security.Authentication.SslProtocols.Tls11 | System.Security.Authentication.SslProtocols.Tls,
         ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true
    };

Below is complete solution of above problem :

    HttpMessageHandler handler = new HttpClientHandler
                    {
                        SslProtocols = System.Security.Authentication.SslProtocols.Tls12 | System.Security.Authentication.SslProtocols.Tls11 | System.Security.Authentication.SslProtocols.Tls,
                        ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true
                    };
var httpClient = new HttpClient(handler);
    httpClient.Timeout = TimeSpan.FromMinutes(60);
        httpClient.BaseAddress = new Uri("https://onpremise");
        httpClient.DefaultRequestHeaders.Accept.Clear();
        httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        //Simple Get Request to test on-premise service
        var response = await httpClient.GetStringAsync("api/OnPremiseData/GetData");
        ViewBag.ResponseText = response;
Tom Sun - MSFT
  • 24,161
  • 3
  • 30
  • 47
arpan desai
  • 889
  • 2
  • 13
  • 23