Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Display the proxy authentication dialog in C#

to access the internet I am behind a proxy that requires authentication. I know it's quite simple to pass the network credentials to the proxy like this:

FtpWebRequest request = FtpWebRequest.Create(
                        new Uri("ftp://upload.myserver.com") as FtpWebRequest;

NetworkCredential credentials = new NetworkCredential("username", "password");
request.Credentials = credentials;

This works!

I also tried to use CredentialCache.DefaultNetworkCredentials but that doesn't work. I want to avoid storing user name and password anywhere (code, database, config file).

I thought the easiest way would be to use the same dialog that is displayed when I access the internet using Internet Explorer. Does anybody knows how to raise this dialog?

http://services.arcgisonline.com/arcgisexplorer500/help/proxy_connect_to_on_browser_request.png

EDIT

The goal of this task was to upload a file via FTP. Finally I found out that it is not necessary to set a proxy for FTP requests because .NET framework does not allow FTP operation through HTTP proxies. But you have to set the proxy property explicitly to null.

FtpWebRequest request = FtpWebRequest.Create(
                        new Uri("ftp://upload.myserver.com") as FtpWebRequest;

NetworkCredential credentials = new NetworkCredential("username", "password");
request.Credentials = credentials;
request.Proxy = null;

Thats it!

like image 884
Jan Avatar asked Nov 17 '10 13:11

Jan


2 Answers

In the MSDN article "Handling Authentication", the author writes:

Proxy Authentication

When a client attempts to use a proxy that requires authentication, the proxy returns a 407 status code message to the client. In that message, the proxy should include one or more Proxy-Authenticate response headers. These headers include the authentication methods available from the proxy. WinINet chooses the first method it recognizes.

The InternetErrorDlg function can be used to obtain the user name and password data from the user, or a customized user interface can be designed.

After searching a little bit longer, I found the Microsoft Knowledge Base article "How To Handle Proxy Authorization with WinInet" which gives an example on how to use this function to authenticate the proxy user.

They provide a (C++) example code with:

if ( InternetErrorDlg (GetDesktopWindow(),
      hReq, ERROR_INTERNET_INCORRECT_PASSWORD,
      FLAGS_ERROR_UI_FILTER_FOR_ERRORS |
      FLAGS_ERROR_UI_FLAGS_GENERATE_DATA |
      FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS,
      NULL) == ERROR_INTERNET_FORCE_RETRY)
            goto again;

(See this MSDN blog post for a P/Invoke example of the InternetErrorDlg function).

The "Handling Authentication" article further states:

A custom interface can use the InternetSetOption function to set the INTERNET_OPTION_PROXY_PASSWORD and INTERNET_OPTION_PROXY_USERNAME values and then resend the request to the proxy.

So I would assume that the following "workflow" could succeed:

  1. Set the proxy to use the default proxy with something like request.Proxy = WebRequest.GetSystemWebProxy().
  2. Request URL with HttpWebRequest (or FtpWebRequest).
  3. If 407 HTTP status code is return, call the InternetErrDlg function.
  4. Retry the URL request.

This could work since this answer states that he successfully used WebRequest when he just recently opened Internet Explorer and entered his proxy credentials there.

So my assumption is that the proxy information is stored somewhere in the Windows "user session" as long as the user is logged in, and is available to all applications after authentication.

Since I'm facing the same issue as the original poster, I'll now try to see how my suggestions actually work.

like image 194
Uwe Keim Avatar answered Nov 08 '22 15:11

Uwe Keim


First of all, id say that this is not an IE dialog. It should be a buildin system dialog.
Further if you invoke it, you still will need to access the entered values and use those in your code. That dialog is just an input window, it won't give your application access to the proxy/internet! Also all error handling (wrong, credentials, etc) have to be done by yourself.
I think it might be easier, to check if a proxy is required (using windows registry, wmi, etc) and pop up a custom form where you can easisly access and reuse the values.

like image 38
Jaster Avatar answered Nov 08 '22 14:11

Jaster