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

Commit d3fd2bb

Browse files
committed
Fix exception handling with AuthenticationSchemeDelegateSelector
1 parent bd02f0e commit d3fd2bb

File tree

6 files changed

+32
-14
lines changed

6 files changed

+32
-14
lines changed

src/System.Net.HttpListener/src/System.Net.HttpListener.csproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@
8484
<Compile Include="$(CommonPath)\System\Net\CaseInsensitiveAscii.cs">
8585
<Link>Common\System\Net\CaseInsensitiveAscii.cs</Link>
8686
</Compile>
87+
<Compile Include="$(CommonPath)\System\Net\ExceptionCheck.cs">
88+
<Link>Common\System\Net\ExceptionCheck.cs</Link>
89+
</Compile>
8790
<Compile Include="$(CommonPath)\System\Net\HttpStatusDescription.cs">
8891
<Link>Common\System\Net\HttpStatusDescription.cs</Link>
8992
</Compile>
@@ -122,9 +125,6 @@
122125
<Compile Include="$(CommonPath)\System\Net\DebugSafeHandle.cs">
123126
<Link>Common\System\Net\DebugSafeHandle.cs</Link>
124127
</Compile>
125-
<Compile Include="$(CommonPath)\System\Net\ExceptionCheck.cs">
126-
<Link>Common\System\Net\ExceptionCheck.cs</Link>
127-
</Compile>
128128
<Compile Include="$(CommonPath)\System\Net\InternalException.cs">
129129
<Link>Common\System\Net\InternalException.cs</Link>
130130
</Compile>

src/System.Net.HttpListener/src/System/Net/HttpListenerContext.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ public sealed unsafe partial class HttpListenerContext
1818

1919
public IPrincipal User => _user;
2020

21+
// This can be used to cache the results of HttpListener.AuthenticationSchemeSelectorDelegate.
22+
internal AuthenticationSchemes AuthenticationSchemes { get; set; }
23+
2124
public HttpListenerResponse Response
2225
{
2326
get

src/System.Net.HttpListener/src/System/Net/Managed/HttpListener.Managed.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -339,8 +339,7 @@ public HttpListenerContext EndGetContext(IAsyncResult asyncResult)
339339
}
340340

341341
HttpListenerContext context = ares.GetContext();
342-
context.ParseAuthentication(SelectAuthenticationScheme(context));
343-
342+
context.ParseAuthentication(context.AuthenticationSchemes);
344343
return context;
345344
}
346345

src/System.Net.HttpListener/src/System/Net/Managed/ListenerAsyncResult.Managed.cs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,11 +112,30 @@ internal void Complete(HttpListenerContext context, bool synch)
112112
_context = context;
113113
lock (_locker)
114114
{
115-
AuthenticationSchemes schemes = context._listener.SelectAuthenticationScheme(context);
116-
if ((schemes == AuthenticationSchemes.Basic || context._listener.AuthenticationSchemes == AuthenticationSchemes.Negotiate) && context.Request.Headers["Authorization"] == null)
115+
bool selectionFailure = false;
116+
try
117117
{
118-
context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
119-
context.Response.Headers["WWW-Authenticate"] = schemes + " realm=\"" + context._listener.Realm + "\"";
118+
context.AuthenticationSchemes = context._listener.SelectAuthenticationScheme(context);
119+
}
120+
catch (OutOfMemoryException oom)
121+
{
122+
context.AuthenticationSchemes = AuthenticationSchemes.Anonymous;
123+
_exception = oom;
124+
}
125+
catch
126+
{
127+
selectionFailure = true;
128+
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
129+
}
130+
131+
if (selectionFailure ||
132+
((context.AuthenticationSchemes == AuthenticationSchemes.Basic || context._listener.AuthenticationSchemes == AuthenticationSchemes.Negotiate) && context.Request.Headers["Authorization"] == null))
133+
{
134+
if (!selectionFailure)
135+
{
136+
context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
137+
context.Response.Headers["WWW-Authenticate"] = context.AuthenticationSchemes + " realm=\"" + context._listener.Realm + "\"";
138+
}
120139
context.Response.OutputStream.Close();
121140
IAsyncResult ares = context._listener.BeginGetContext(_cb, _state);
122141
_forward = (ListenerAsyncResult)ares;

src/System.Net.HttpListener/src/System/Net/Windows/HttpListenerContext.Windows.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,6 @@ internal void SetIdentity(IPrincipal principal, string mutualAuthentication)
3434
if (NetEventSource.IsEnabled) NetEventSource.Info(this, $"mutual: {(mutualAuthentication == null ? "<null>" : mutualAuthentication)}, Principal: {principal}");
3535
}
3636

37-
// This can be used to cache the results of HttpListener.AuthenticationSchemeSelectorDelegate.
38-
internal AuthenticationSchemes AuthenticationSchemes { get; set; }
39-
4037
// This can be used to cache the results of HttpListener.ExtendedProtectionSelectorDelegate.
4138
internal ExtendedProtectionPolicy ExtendedProtectionPolicy { get; set; }
4239

src/System.Net.HttpListener/tests/AuthenticationTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ public async Task AuthenticationSchemeSelectorDelegate_ReturnsInvalidAuthenticat
229229
}
230230
}
231231

232-
[ConditionalFact(nameof(Helpers) + "." + nameof(Helpers.IsWindowsImplementation))] // [ActiveIssue(20100, TestPlatforms.AnyUnix)]
232+
[ConditionalFact(nameof(PlatformDetection) + "." + nameof(PlatformDetection.IsNotOneCoreUAP))]
233233
public async Task AuthenticationSchemeSelectorDelegate_ThrowsException_SendsInternalServerErrorToClient()
234234
{
235235
_listener.AuthenticationSchemes = AuthenticationSchemes.Basic;
@@ -241,7 +241,7 @@ public async Task AuthenticationSchemeSelectorDelegate_ThrowsException_SendsInte
241241
}
242242
}
243243

244-
[ConditionalFact(nameof(Helpers) + "." + nameof(Helpers.IsWindowsImplementation))] // [ActiveIssue(20100, TestPlatforms.AnyUnix)]
244+
[ConditionalFact(nameof(PlatformDetection) + "." + nameof(PlatformDetection.IsNotOneCoreUAP))]
245245
public void AuthenticationSchemeSelectorDelegate_ThrowsOutOfMemoryException_RethrowsException()
246246
{
247247
_listener.AuthenticationSchemes = AuthenticationSchemes.Basic;

0 commit comments

Comments
 (0)