Empty challenge for authenticated request should result in Forbidden.

This commit is contained in:
Chris R 2015-07-10 14:50:11 -07:00
parent 2b5785c2c6
commit c9f0a47c0d
2 changed files with 27 additions and 3 deletions

View File

@ -68,12 +68,12 @@ namespace Microsoft.AspNet.Server.WebListener
public Task ChallengeAsync(ChallengeContext context)
{
var hasEmptyChallenge = string.IsNullOrEmpty(context.AuthenticationScheme);
foreach (var scheme in ListEnabledAuthSchemes())
{
var authScheme = scheme.ToString();
// Not including any auth types means it's a blanket challenge for any auth type.
if (string.IsNullOrEmpty(context.AuthenticationScheme) ||
string.Equals(context.AuthenticationScheme, authScheme, StringComparison.Ordinal))
if (hasEmptyChallenge || string.Equals(context.AuthenticationScheme, authScheme, StringComparison.Ordinal))
{
switch (context.Behavior)
{
@ -89,7 +89,7 @@ namespace Microsoft.AspNet.Server.WebListener
case ChallengeBehavior.Automatic:
var identity = (ClaimsIdentity)_requestContext.User?.Identity;
if (identity != null && identity.IsAuthenticated
&& string.Equals(identity.AuthenticationType, context.AuthenticationScheme, StringComparison.Ordinal))
&& (hasEmptyChallenge || string.Equals(identity.AuthenticationType, context.AuthenticationScheme, StringComparison.Ordinal)))
{
_requestContext.Response.StatusCode = 403;
context.Accept();

View File

@ -460,6 +460,30 @@ namespace Microsoft.AspNet.Server.WebListener
}
}
[Theory]
[InlineData(AuthenticationSchemes.Kerberos)]
[InlineData(AuthenticationSchemes.Negotiate)]
[InlineData(AuthenticationSchemes.NTLM)]
// [InlineData(AuthenticationSchemes.Digest)] // Not implemented
// [InlineData(AuthenticationSchemes.Basic)] // Can't log in with UseDefaultCredentials
public async Task AuthTypes_ChallengeAuthenticatedAuthTypeWithEmptyChallenge_Forbidden(AuthenticationSchemes authType)
{
string address;
using (Utilities.CreateHttpAuthServer(authType, out address, env =>
{
var context = new DefaultHttpContext((IFeatureCollection)env);
Assert.NotNull(context.User);
Assert.True(context.User.Identity.IsAuthenticated);
return context.Authentication.ChallengeAsync();
}))
{
var response = await SendRequestAsync(address, useDefaultCredentials: true);
Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode);
// for some reason Kerberos and Negotiate include a 2nd stage challenge.
// Assert.Equal(0, response.Headers.WwwAuthenticate.Count);
}
}
[Theory]
[InlineData(AuthenticationSchemes.Kerberos)]
[InlineData(AuthenticationSchemes.Negotiate)]