Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit be49d38

Browse files
davidshstephentoub
authored andcommitted
Fix WinHttpHandler when using authenticating proxies (#30212)
This was a regression from .NET Core 2.0 due to PR #28105. Proxy authentication using system default proxy settings that involve a PAC file (either autodiscovery or explicit PAC file) cause a NullReferenceException in WinHttpHandler in the CheckResponseForAuthentication() method. This problem is only discovered when using an authenticating proxy server (any auth scheme) that is discovered using PAC files. This is considered the "system default" proxy. When this occurs, the handler's Proxy property is null and dereferencing it caused the exception. Due to the problems described in #6997, the uri of the proxy can't be determined yet since it is only known to WinHTTP. Fixing #6997 is complicated and impacts performance. However, in most cases, as long as the credentials are a NetworkCredential object, knowing the uri of the proxy is needed. I tested this manually using the steps I described in #30191. I did not add any tests to this PR since they can't be run in CI. However, I am working on a task that will eventually add Enterprise-Scenario testing like this (PAC files, authenticating proxies, etc.) to our systems. Fixes #30191 Contributes to #6997
1 parent 09be1e9 commit be49d38

File tree

1 file changed

+17
-2
lines changed

1 file changed

+17
-2
lines changed

src/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinHttpAuthHelper.cs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,15 +147,21 @@ public void CheckResponseForAuthentication(
147147
out authTarget))
148148
{
149149
// WinHTTP returns an error for schemes it doesn't handle.
150-
// So, we need to ignore the error and just let it stay at 401.
150+
// So, we need to ignore the error and just let it stay at 407.
151151
break;
152152
}
153153

154154
// WinHTTP returns the proper authTarget based on the status code (401, 407).
155155
// But we can validate with assert.
156156
Debug.Assert(authTarget == Interop.WinHttp.WINHTTP_AUTH_TARGET_PROXY);
157157

158-
proxyAuthScheme = ChooseAuthScheme(supportedSchemes, state.Proxy.GetProxy(state.RequestMessage.RequestUri), proxyCreds);
158+
proxyAuthScheme = ChooseAuthScheme(
159+
supportedSchemes,
160+
// TODO: Issue #6997. If Proxy==null, we're using the system proxy which is possibly
161+
// discovered/calculated with a PAC file. So, we can't determine the actual proxy uri at
162+
// this point since it is calculated internally in WinHTTP. For now, pass in null for the uri.
163+
state.Proxy?.GetProxy(state.RequestMessage.RequestUri),
164+
proxyCreds);
159165
state.RetryRequest = true;
160166
break;
161167

@@ -378,6 +384,15 @@ private static uint ChooseAuthScheme(uint supportedSchemes, Uri uri, ICredential
378384
return 0;
379385
}
380386

387+
if (uri == null && !(credentials is NetworkCredential))
388+
{
389+
// TODO: Issue #6997.
390+
// If the credentials are a NetworkCredential, the uri isn't used when calling .GetCredential() since
391+
// it will work against all uri's. Otherwise, credentials is probably a CredentialCache and passing in
392+
// null for a uri is invalid.
393+
return 0;
394+
}
395+
381396
foreach (uint authScheme in s_authSchemePriorityOrder)
382397
{
383398
if ((supportedSchemes & authScheme) != 0 && credentials.GetCredential(uri, s_authSchemeStringMapping[authScheme]) != null)

0 commit comments

Comments
 (0)