0

I have a class library to perform Rest API calls built in 4.6.1 framework. I have used System.Net.Http V4 HttpClient for managing calls. This library works in normal dotnet apps. Recently I tried it for a DotNet Core app, it failed with security error. Later I modified library as suggested in post. It had some progress but the app fails with error as shown below

Error message: An error occurred while sending the request. Innerexception message: A security error occurred. StackTrace: at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Threading.Tasks.RendezvousAwaitable`1.GetResult() at System.Net.Http.WinHttpHandler.d__105.MoveNext()

Library Code:

private readonly HttpClient _client = null;
private ICredentials somecred;

    public Program()
    {
        HttpClientHandler clientHandler = new HttpClientHandler { Credentials = somecred, UseDefaultCredentials = false };
        _client=new HttpClient(new MessageHandler(clientHandler, TimeSpan.FromSeconds(1), 1), false);
        _client.Timeout = TimeSpan.FromSeconds(90);
        _client.BaseAddress = new Uri("https://somedomain.com/");

        ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
        ServicePointManager.DefaultConnectionLimit = 10;
        ServicePointManager.Expect100Continue = true;
    }

    public async Task<IOperationResponse> GetData()
    {
        ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

        using (HttpResponseMessage httpResponse =
                await _client.SendAsync(new HttpRequestMessage(HttpMethod.Head, "api/getdata"), HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false)
                )
        {
            if (httpResponse != null) { ... }
        }
    }

    internal class MessageHandler : DelegatingHandler
    {
        public MessageHandler(HttpMessageHandler innerHandler, TimeSpan retryInterval, int retryCount) : base(innerHandler)
        {

        }

        protected override async Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request,
        CancellationToken cancellationToken)
        {
            HttpResponseMessage response = null;

            //!! security error in below line
            response = await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
        }
    }

Please let me know, what needs to be done for this library to run for DotNet Core apps. Thanks.

prvn
  • 406
  • 3
  • 7
  • 24

2 Answers2

2

I have tested your code locally with a core project and an external 4.5 library and the only way I could get the security error to trigger was if the target site did not have the correct level of security (i.e was not correctly setup with SSL). When targeting a site that had SSL configured correctly the call went through.

Ensure that your target has SSL setup or target another known working SSL site to test against to see if you still encounter the issue.

Henry
  • 2,187
  • 1
  • 15
  • 28
  • you might be right. The target is a vendor, i do not have much control over. Is there any way to test if target has setup SSL from my end? – prvn Feb 11 '18 at 11:19
  • Go to the URL in question with https:// in your browser and see if it does indeed serve up a certificate. There are also online tools that can scan a site (assuming its not a private url). – Henry Feb 12 '18 at 19:05
0

I made following code change as per my colleague suggestion and that fixed it.

//original code
_client.BaseAddress = new Uri("https://xyz.abc.somedomain.com/");

//fix code
_client.BaseAddress = new Uri("https://abc.somedomain.com/");
_client.DefaultRequestHeaders.Host = "xyz.abc.somedomain.com";

I'm marking this as answer, though i do not completely understand this behavior.

prvn
  • 406
  • 3
  • 7
  • 24