As per MS Support article 917952:
FIX: Error message when you try to install a ClickOnce application that you created in the .NET Framework 2.0 onto a client computer that is configured to use a proxy server: "Proxy authentication required"
1-You create a ClickOnce application in the Microsoft .NET Framework 2.0.
2-You publish the ClickOnce application to a deployment server.
3-A client computer is configured to use a proxy server that requires authentication.
->
In this scenario, when you try to install the ClickOnce application from the deployment server onto the client computer, you receive the following error message:
The remote server returned an error: (407) Proxy Authentication Required.
This happens because the CLR isn't using the default proxy and proxy credentials.
The comon fix is to edit the machine.config file of the client computer and insert
<defaultProxy enabled="true" useDefaultCredentials="true">
Another fix is using some lines like
DataSet myds = new DataSet();
//Set the system proxy with valid server address or IP and port.
System.Net.WebProxy pry = new System.Net.WebProxy("172.16.0.1",8080);
//The DefaultCredentials automically get username and password.
pry.Credentials = CredentialCache.DefaultCredentials;
GlobalProxySelection.Select = pry;
myds.ReadXml("http://msdn.microsoft.com/netframework/rss.xml", XmlReadMode.Auto);
myds.WriteXmlSchema(@"c:\\f.xml");
this.GridView1.DataSource = myds.Tables[2];
this.GridView1.DataBind();
Where should this fix go? On the data portal code?
It looks like that GlobalProxySelection is obsolete (according to MSDN). They recommend this:
http://msdn2.microsoft.com/en-us/library/kd3cf2ex.aspx
With the WCF proxy you should be able to set this in the config
file.
With Remoting you need to create your own RemotingProxy class. I
recommend just copying the code from Csla\DataPortal\Client\RemotingProxy into
your project, then altering the constructor code where it configures Remoting.
I probably should have made the Remoting proxy more like the WCF
one, where you do everything through the config file, but I won’t go back
and enhance Remoting now since people should be migrating to WCF anyway.
Rocky
Here is the definitive answer that worked for me:
ISA Proxy Server (and I imagine others as well), have the option of requesting credentials before passing a webrequest on to the appropriate webservice.
If the ISA Proxy Server DOES NOT request credentials, then your CSLA ClickOnce app will communicate with the Webserverportal with no modification to app.config or anything else.
If the ISA Proxy Server DOES request credentials, then your CSLA ClickOnce app will have to be modified to communicate with the Webserverportal.
Background: System.Net.WebRequest.DefaultWebProxy, picks up the proxy server settings in IE. When a HttpWebRequest is routed to an ISA Proxy Server that requests credentials, you can no longer use the System.Net.WebRequest.DefaultWebProxy and must create a new WebProxy, set its .UseDefaultCredentials = true, and then set the System.Net.WebRequest.DefaultWebProxy to the newly created WebProxy object.
I have not gotten a full answer on this, but it is similar to why the IE settings of "Automatically Detect Settings" or "Automatic Configuration Script" settings cannot be detected or set in the System.Net.WebRequest.DefaultWebProxy. When I get an answer on how to get around this, I will update this post.
I suspect you can attain the same results attained by the following code by setting the <system.net> settings in the app.config file, I just never tried because I wanted the user to be able to set their own proxyserver address. The following code shows how to create and set the proxy object programatically.
No code modifications are required to CSLA. The following code can be run in MainForm_Load.
Please note that all calls to the following object, CodeQwik.Common.Proxy.LANSettings, are static calls to variables that are set elsewhere.
//MainForm_Load
if (CodeQwik.Common.Proxy.LANSettings.UseProxyServer)
{
int port = 0;
if (!int.TryParse(CodeQwik.Common.Proxy.LANSettings.ProxyPort, out port))
port = 80;
// I CANNOT STRESS ENOUGH HOW IMPORTANT IT IS TO BE CAREFUL
// ABOUT HOW YOU USE THE System.Net.WebProxy() CONSTRUCTORS.
string proxyServerUrl = CodeQwik.Common.Proxy.LANSettings.ProxyServerUrl.ToLower().Replace("http://", "");
System.Net.WebProxy proxy = new System.Net.WebProxy(proxyServerUrl, port);
// When you use this constructor with port 80 or 8080, no "http://", otherwise the result is http://http://myproxy.local
// You can accomplish the same thing like this:
//string proxyServerUrlAndPort= CodeQwik.Common.Proxy.LANSettings.ProxyServerUrl.ToLower().Contains("http://") ?
// CodeQwik.Common.Proxy.LANSettings.ProxyServerUrl : "http://" + CodeQwik.Common.Proxy.LANSettings.ProxyServerUrl;
//proxyServerUrlAndPort+= ":" + port.ToString();
//System.Net.WebProxy proxy = new System.Net.WebProxy(proxyServerUrlAndPort);
//...but if you do, YOU MUST MAKE SURE the ProxyAddress has "http://" in it.
//One or both of the following lines are critical if the ISA Proxy Server requests
//Integrated NTLM/Kerberos Authentication credentials
proxy.UseDefaultCredentials = true;
proxy.Credentials = System.Net.CredentialCache.DefaultCredentials;
//Use the following if authentication is not Integrated NTLM/Kerberos Authentication,
//ie., you must enter a UN/PWD in IE to view a website.
//proxy.Credentials = new NetworkCredentials("username", "password");
System.Net.WebRequest.DefaultWebProxy = proxy;
}
That is all there is to it!
Dave Boal
www.codeqwik.net
Copyright (c) Marimer LLC