1
votes

I am facing one odd problem, I was able to make this (https://my.factcorp.com/ABCorp/Reporting/api/Events/) Rest API call from POSTMAN, but not from Visual Studio Web Test.

PostMan call trace

GET https://my.factcorp.com/ABCorp/Reporting/api/Events/ HTTP/1.1

Host: my.factcorp.com

Connection: keep-alive

Authorization: Basic

Cache-Control: no-cache

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36

Postman-Token: 4dfaa309-c7d8-6785-d59c-9679ad4f3aaa

Accept: /

Accept-Encoding: gzip, deflate, sdch, br

Accept-Language: en-US,en;q=0.8

Whereas, when I am making a call for same rest API from Webtest, getting below error

Request failed: An existing connection was forcibly closed by the remote host

I can see Postman has added some extra header to the request, I also tried that by adding manually all those headers.

Any thought appreciated.

Thanks

1

1 Answers

2
votes

Actually found the root cause, why the call is getting successful from Postman and not from VS WebTest.

The reason is Postman enough intelligent to the correct the request security to (TLS/1.2)

Whereas WebTest is not able to do that, since it uses lower level System.Net protocol.

Now to solve this problem we can actually write the custom WebTest Plugin which can overwrite the default security behavior.

using System;
using System.ComponentModel;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using Microsoft.VisualStudio.TestTools.WebTesting;

namespace MyWebTest
{
    [Description("This plugin will force the underlying System.Net ServicePointManager to negotiate downlevel SSLv3 instead of TLS. WARNING: The servers X509 Certificate will be ignored as part of this process, so verify that you are testing the correct system.")]
    public class TLS12ForcedPlugin : WebTestPlugin
    {

        [Description("Enable or Disable the plugin functionality")]
        [DefaultValue(true)]
        public bool Enabled { get; set; }

        public override void PreWebTest(object sender, PreWebTestEventArgs e)
        {
            base.PreWebTest(sender, e);

            //For TLS
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

            //For SSL
            //ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;

            //we wire up the callback so we can override  behavior and force it to accept the cert
            ServicePointManager.ServerCertificateValidationCallback = RemoteCertificateValidationCB;

            //let them know we made changes to the service point manager
            e.WebTest.AddCommentToResult(this.ToString() + " has made the following modification-> ServicePointManager.SecurityProtocol set to use SSLv3 in WebTest Plugin.");
        }
        public static bool RemoteCertificateValidationCB(Object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
        {
            //If it is really important, validate the certificate issuer here.
            //this will accept any certificate
            return true;
        }
    }
}