HTTP 407 (requires proxy authentication)

I have some basic questions about HTTP authentication

1) How does the client know about the server authentication type (Basic / Digest / NTLM) HTTP?
is configurable on the HTTP server side?

My answer: The server will be installed with the type of authentication it needs to do with the client. So our client API (in the C # HttpWebRequest API) will take care of this automatically. Best use of Wireshrk with HTTP filtering; you will get the source and destination IP address at the internet protocol layer. Both the src and dest port in the transmission control protocol and the type of authentication at the http level.

2) If I set up a squid linux proxy between client and server; is there any need for my client code to also know about the proxy authentication type? or is the authentication type only associated with the final HTTP server?

My answer: If the squid proxy is between client and server; it won't use HTTP authentication. It can use a) DB: Uses SQL database. B) LDAP: Uses lightweight directory access protocol. c) RADIUS: Uses a RADIUS server for login authentication. and so on .. Therefore, we must specify the proxy authentication credentials in the HTTP headers.

3) Using WireShark showed that there are three requests from the browser to the server to make a single request.

a) The browser sends the request without any credentials; So the server responded with a 401 along with the relam and nonce.

WWW-Authenticate: Digest realm="realm", qop="auth", nonce="MTM1OTYyMzkyNDU4MzpiOWM0OWY0NmMzMzZlMThkMDJhMzRhYmU5NjgwNjkxYQ=="\r\n <BR>

      

b) The second time the browser sends a request with credentials, relam, nonce, cnonce; but still the server responded with 401;

WWW-Authenticate: Digest realm="realm", qop="auth", nonce="MTM1OTYyMzk0OTAyMTo3Njk3MDNhZTllZDQyYzQ5MGUxYzI5MWY2MGU5ZDg0Yw==", stale="true"\r\n

      

c) The third time the browser sends the same request with the same credentials, relam, nonce, cnonce. This time the server will send 200 ok.

My question is for the second and third time the Browser sends the same request; why the server didn't execute the second time and succeeded the third time. Is it because of my server implementation? (I have a Java REST server with a SPRING security filter).

I have a C # HTTP client;

the first time the HttpWebRequest is sent without credentials even though System.Net.NetworkCredentials is set; so the client got 407 with relat and nonce.
Second time HttpWebRequest is scuccess. The third request from this client, like a browser, is missing.

Why is this the difference between browser and C # client?

My answer: I still don't know what's going on here: Q3.

4) Now the real problem I am facing is when the SQUID LINUX PROXY comes in between our client and the HTTP server, the browser did the same three request authentication and succeeded. However, C # HttpWebRequest failed (401) on the second request and got to the cache (exception) {} and didn't try a third time.

Could you please tell me how to solve this problem in C # client when PROXY SERVER is in between?

Below code makes a GET request.

  HttpWebRequest request = WebRequest.Create("url") as HttpWebRequest;
  request.Credentials = new NetworkCredential(loginUserName, password);
  WebResponse response = request.GetResponse(); 

      

Please note that our proxy request is sent over TCP and not over HTTP. The HTTP protocol is then passed from PROXY to SERVER. But the HTTP request from the Proxy contains our client ip information in the HTTP header X-Forwarded-For

.

Below are possible solutions

These solutions are only needed if your proxy requires any kind of authentication, otherwise ignore it.

Solution 1: work for me

request.Proxy.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;

      

Solution 2:

  IWebProxy proxy = WebRequest.GetSystemWebProxy();
  proxy.Credentials = new NetworkCredential(UserName, UserPassword, UserDomain);
  request.Proxy = proxy;

      

Solution 3 given by Martin:

  var proxy = new WebProxy ("http://localhost:3128/");
  proxy.Credentials = new NetworkCredential (UserName, UserPassword, UserDomain);
  request.Proxy = proxy;

      

Learn more about proxy authentication http://wiki.squid-cache.org/Features/Authentication

+3


source to share


1 answer


It is a call / response protocol. Typically, the client makes the initial request without any authentication headers (you can set request.PreAuthenticate = true

to send credentials with the first request).

The server then responds with a list of authentication methods it supports.

If the user has not explicitly specified the using authentication method CredentialsCache

, the runtime will try all of them, from strongest to weakest. Some protocols (like NTLM) require multiple requests from client to server. In theory Digest should work with one, not sure why it sends the request twice.

Regarding your proxy request, there are two different types of authentication:

  • Authenticating the target web server, the proxy just passes it on, although you don't need any special code in your client.
  • In addition to this, the proxy server itself may also require authentication, which may be different from the one specified in the target web server.

You specify them with

var proxy = new WebProxy ("http://localhost:3128/");
proxy.Credentials = new NetworkCredential ("username", "password");

      



and then

WebRequest.DefaultWebProxy = proxy;

      

or

request.Proxy = proxy;

      

Don't set credentials in WebProxy

unless your proxy uses authentication.

If you can't get the authentication to work when using a proxy, take a look at the actual requests that are sent between the three parties (web server, proxy, client) using Wireshark.

+3


source







All Articles