Explicitely specify Default user credentials for Web Proxy Server.

Some time ago I wrote post “Call Web Services through SQuid proxy server with authentication requested”  and hoped, that I will not have more problems with Squid web proxy server.
However teh solution wasn’t sufficient for other site. I’ve tried a lot of things, started thread “Unable to access external web sites through Squid proxy server with required authentication.” and posted suggestion to Microsoft “Add ability to specify credentials to defaultProxy configuration element“.

But the best solution, that I found for the moment is  to create common function to set web proxy credentials and call it  for each Web Services call,HttpWebRequest call and replace  dataset.ReadXml(url)  with HttpWebRequest.GetRequest.
The function created expects up to 4 properties in appSettings section of Web.config
        <!–Web Proxy Credentials to use if useDefaultCredentials=”true” doesn’t help

    TODO move to separate ConfigurationSection, different from AppSettings

    <add key=”ProxyUserName” value=””/>

    <add key=”ProxyUserPassword” value=””/>

    <add key=”ProxyAuthenticationType” value=”Basic”/>

    <add key=”ProxyUserDomain” value=””/>

    –>
and to be called like the following for web services


 

        AWSECommerceService aws = new AWSECommerceService();

         SetDefaultWebProxyCredentialsIfRequired(aws);

 

or for dataset.ReadXml

 

        IWebProxy proxyObject = CreateDefaultWebProxyWithCredentialsIfRequired(url);//WSClientHelper.

        if (proxyObject == null)

            ds.ReadXml(url);

        else

        {

            Stream strm = GetResponseStream(url, proxyObject);//HttpWebRequestHelper.

            ds.ReadXml(strm);

        }

 

The code of the SetDefaultWebProxyCredentialsIfRequired and other helper methods is the following:

 

    public static bool SetDefaultWebProxyCredentialsIfRequired(SoapHttpClientProtocol ws)

    {

        IWebProxy proxyObject = CreateDefaultWebProxyWithCredentialsIfRequired(ws.Url);

        //bool bRet =SetDefaultWebProxyCredentialsIfRequired(ws, ProxyUserName, ProxyUserPassword, sAuthType, ProxyUserDomain);

        bool bRet = SetDefaultWebProxyCredentials(ws, proxyObject);

        return bRet;

    }

    /// <summary>

    ///

    /// </summary>

    /// <param name=”ws”></param>

    /// <param name=”proxyObject”>if null, no proxy is set</param>

    /// <returns></returns>

    public static bool SetDefaultWebProxyCredentials(SoapHttpClientProtocol ws, IWebProxy proxyObject)

    {

        bool bRet = false;

        if (null == proxyObject) return false;

            ws.Proxy = proxyObject;

            ws.PreAuthenticate = true;//from http://www.awprofessional.com/articles/article.asp?p=27574&seqNum=3

            ws.AllowAutoRedirect = true;

            bRet = true;

            //ws.Credentials = cache;

        return bRet;

    }//SetDefaultWebProxyCredentialsIfRequired

    /// <summary>

    /// If configuration parameters for ProxyUserName and ProxyUserPassword are specified, returns IWebProxy object, otherwise returns null

    /// </summary>

    /// <param name=”sUrl”></param>

    /// <returns></returns>

    public static IWebProxy CreateDefaultWebProxyWithCredentialsIfRequired(String sUrl)

    {

        //TODO move to separate ConfigurationSection, different from AppSettings

        string ProxyUserName = ConfigurationManager.AppSettings[“ProxyUserName”];

        string ProxyUserPassword = ConfigurationManager.AppSettings[“ProxyUserPassword”];

        string sAuthType = ConfigurationManager.AppSettings[“ProxyAuthenticationType”];

        string ProxyUserDomain = ConfigurationManager.AppSettings[“ProxyUserDomain”];

        IWebProxy proxyObject = CreateWebProxyWithCredentials(sUrl, ProxyUserName, ProxyUserPassword, sAuthType, ProxyUserDomain);

        return proxyObject;

    }

    /// <summary>

    ///

    /// </summary>

    /// <param name=”sUrl”></param>

    /// <param name=”ProxyUserName”>if parameter is null, the function returns null</param>

    /// <param name=”ProxyUserPassword”>if parameter is null, the function returns null</param>

    /// <param name=”sAuthType”>defaults to “basic”</param>

    /// <param name=”ProxyUserDomain”>ignored for “basic” authentication type</param>

    /// <returns></returns>

    public static IWebProxy CreateWebProxyWithCredentials(String sUrl, string ProxyUserName, string ProxyUserPassword, string sAuthType, string ProxyUserDomain)

    {

        if (String.IsNullOrEmpty(ProxyUserName) || String.IsNullOrEmpty(ProxyUserPassword))

        {

            return null;

        }

        // get default proxy and assign it to the WebService. Alternatively, you can replace this with manual WebProxy creation.

        IWebProxy iDefaultWebProxy = WebRequest.DefaultWebProxy;

        Uri uriProxy = iDefaultWebProxy.GetProxy(new Uri(sUrl));

        string sProxyUrl = uriProxy.AbsoluteUri;

        if (sProxyUrl == sUrl)

        {//no proxy specified

            return null;

        }

        IWebProxy proxyObject = new WebProxy(sProxyUrl, true);

        // assign the credentials to the Proxy

        //todo do we need to add credentials to  WebService too??

        if ((!String.IsNullOrEmpty(sAuthType)) && (sAuthType.ToLower() != “basic”))

        {

            //from http://www.mcse.ms/archive105-2004-10-1165271.html

            // create credentials cache – it will hold both, the WebProxy credentials (??and the WebService credentials too??)

            System.Net.CredentialCache cache = new System.Net.CredentialCache();

            // add default credentials for Proxy (notice the authType = ‘Kerberos’ !) Other types are ‘Basic’, ‘Digest’, ‘Negotiate’, ‘NTLM’

            cache.Add(new Uri(sProxyUrl), sAuthType, new System.Net.NetworkCredential(ProxyUserName, ProxyUserPassword, ProxyUserDomain));

            proxyObject.Credentials = cache;

        }

        else//special case for Basic (from http://www.xmlwebservices.cc/index_FAQ.htm )

        {

            proxyObject.Credentials = new System.Net.NetworkCredential(ProxyUserName, ProxyUserPassword);

        }

        return proxyObject;

    }

    //Default methos is Get, do not store cookies

    public static Stream GetResponseStream(string sUrl, IWebProxy proxy)

    {// string Method, CookieContainer cntnrCookies, string sFileToSaveHtml

        //            HttpWebRequest webRequest = HttpWebRequestHelper.PrepareWebRequest(sUrl, Method, cntnrCookies);

        HttpWebRequest webRequest = WebRequest.Create(sUrl) as HttpWebRequest;

        //  webRequest.ContentType = “application/x-www-form-urlencoded”;//is good?

        webRequest.Proxy = proxy;

        //you can  change some properties if required – from http://www.codeproject.com/csharp/ClientTicket_MSNP9.asp         

        //MNF 26/5/2005 Some web servers expect UserAgent to be specified,so let’s say it’s IE6

        webRequest.UserAgent = “Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.1.4322)”;

       // DebugHelper.PrintHttpWebRequest(webRequest, TraceHelper.LineWithTrace(“”));

        HttpWebResponse resp = webRequest.GetResponse() as HttpWebResponse;

        Stream strm = resp.GetResponseStream();

        return strm;//’HttpWebRequestHelper.GetResponseString(resp, sFileToSaveHtml);

    }