I am trying to apply a Proxy authentication through an HttpClient, in a .net standard1.3 library

1.5k views Asked by At

.net Standard 1.3 means -> no WebProxy library. So I have created one, here it is :

   public class WebProxy : IWebProxy, ISerializable
    {
        private readonly ArrayList _bypassList;

        public WebProxy() : this((Uri)null, false, null, null) { }

        public WebProxy(Uri Address) : this(Address, false, null, null) { }

        public WebProxy(Uri Address, bool BypassOnLocal, string[] BypassList, ICredentials Credentials)
        {
            this.Address = Address;
            this.Credentials = Credentials;
            this.BypassProxyOnLocal = BypassOnLocal;
            if (BypassList != null)
            {
                _bypassList = new ArrayList(BypassList);
                UpdateRegExList(true);
            }
        }

        private void UpdateRegExList(bool canThrow)
        {
            Regex[] regExBypassList;
            ArrayList bypassList = _bypassList;
            try
            {
                if (bypassList != null && bypassList.Count > 0)
                {
                    regExBypassList = new Regex[bypassList.Count];
                    for (int i = 0; i < bypassList.Count; i++)
                    {
                        regExBypassList[i] = new Regex((string)bypassList[i], RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
                    }
                }
            }
            catch
            {
                if (!canThrow)
                {
                    return;
                }
                throw;
            }

        }

        public WebProxy(string Host, int Port)
            : this(new Uri("http://" + Host + ":" + Port.ToString(CultureInfo.InvariantCulture)), false, null, null)
        {
        }

        public WebProxy(string Address)
            : this(CreateProxyUri(Address), false, null, null)
        {
        }

        public WebProxy(string Address, bool BypassOnLocal)
            : this(CreateProxyUri(Address), BypassOnLocal, null, null)
        {
        }

        public WebProxy(string Address, bool BypassOnLocal, string[] BypassList)
            : this(CreateProxyUri(Address), BypassOnLocal, BypassList, null)
        {
        }

        public WebProxy(string Address, bool BypassOnLocal, string[] BypassList, ICredentials Credentials)
            : this(CreateProxyUri(Address), BypassOnLocal, BypassList, Credentials)
        {
        }

        public Uri Address { get; set; }

        public bool BypassProxyOnLocal { get; set; }

        public bool IsBypassed(Uri host)
        {
            return true;
        }

        public ICredentials Credentials { get; set; }

        public bool UseDefaultCredentials
        {
            get { return Credentials == CredentialCache.DefaultCredentials; }
            set { Credentials = value ? CredentialCache.DefaultCredentials : null; }
        }

        private Uri proxyUri;
        public Uri GetProxy(Uri destination)
        {
            return proxyUri;
        }

        private static Uri CreateProxyUri(string address) =>
            address == null ? null :
            address.IndexOf("://") == -1 ? new Uri("http://" + address) :
            new Uri(address);

        void ISerializable.GetObjectData(SerializationInfo serializationInfo, StreamingContext streamingContext)
        {
            throw new PlatformNotSupportedException();
        }
    }

I create the HttpClient like so :


     HttpClientHandler handler = new HttpClientHandler()
     {
        Proxy = new WebProxy(proxy.Address, true, new string[0], proxy.Credentials),
        UseProxy = true
     };

     HttpClient httpClient = new HttpClient(handler);

There is no error, no exception, although that is exactly what I am looking for. I set up a proxy using Fiddler, with a username and a password, and in order to test the Proxy, I am intentionally passing another password to the httpClient.

Now, the problem is that the httClient should throw an exception when trying to call for the specified API since the proxy's credentials are the wrong ones.

What am I missing? Feels like httpClient doesn't even see the Proxy at all, although while debugging I can see the credentials being passed to the handler and contained by the httpClient.

1

There are 1 answers

0
Nicole Milea On

I solved it.

Here is the WebProxy class :

 public class WebProxy : IWebProxy, ISerializable
    {

        // Uri of the associated proxy server.
        private readonly Uri webProxyUri;

        public WebProxy(Uri proxyUri)
        {

            webProxyUri = proxyUri;
        }

        public Uri GetProxy(Uri destination)
        {
            return webProxyUri;
        }

        public bool IsBypassed(Uri host)
        {
            return false;
        }


        private ICredentials _credentials;

        // Get and Set the Credentials property.
        public ICredentials Credentials
        {
            get
            {
                return _credentials;
            }
            set
            {
                if (!Equals(_credentials, value))
                    _credentials = value;
            }
        }


        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            throw new NotImplementedException();
        }
    }

And here's how you apply it :

  public static HttpResponseMessage SendGetRequestToStakOverFlow()
        {
            WebProxy proxy = GetConnectionProxy();

            HttpClientHandler handler = new HttpClientHandler()
            {
                Proxy = proxy,
                UseProxy = true
            };

            var httpClient = new HttpClient(handler);

            var response = httpClient
                .GetAsync(
                    "https://stackoverflow.com/questions/62793813/i-am-trying-to-apply-a-proxy-authentication-through-an-httpclient-in-a-net-sta")
                .GetAwaiter()
                .GetResult();
            return response;
        }


        private static WebProxy GetConnectionProxy()
        {

            var proxy = new WebProxy(new Uri("http://localhost:8888"));

            ProxySettings ps = new ProxySettings();
            ps.Password = "myPasscode";
            ps.UserName = "myUser";

            NetworkCredential cred = new NetworkCredential(ps.UserName, ps.Password);
            proxy.Credentials = cred;

            return proxy;
        }


  public class ProxySettings
    {
        public string UserName { get; set; }
        public string Password { get; set; }
    }