Enable custom auth challenges. Integrate IAuthenticationHandler.
This commit is contained in:
parent
0e197a59ed
commit
e15fe540a8
|
|
@ -0,0 +1,148 @@
|
||||||
|
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||||
|
// All Rights Reserved
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||||
|
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||||
|
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||||
|
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||||
|
// NON-INFRINGEMENT.
|
||||||
|
// See the Apache 2 License for the specific language governing
|
||||||
|
// permissions and limitations under the License.
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
// <copyright file="AuthenticationManager.cs" company="Microsoft">
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// </copyright>
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNet.HttpFeature.Security;
|
||||||
|
using Microsoft.Net.Server;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Server.WebListener
|
||||||
|
{
|
||||||
|
internal class AuthenticationHandler : IAuthenticationHandler
|
||||||
|
{
|
||||||
|
private RequestContext _requestContext;
|
||||||
|
private AuthenticationTypes _authTypes;
|
||||||
|
private AuthenticationTypes _customChallenges;
|
||||||
|
|
||||||
|
internal AuthenticationHandler(RequestContext requestContext)
|
||||||
|
{
|
||||||
|
_requestContext = requestContext;
|
||||||
|
_authTypes = requestContext.AuthenticationChallenges;
|
||||||
|
_customChallenges = AuthenticationTypes.None;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Authenticate(IAuthenticateContext context)
|
||||||
|
{
|
||||||
|
var user = _requestContext.User;
|
||||||
|
var identity = user == null ? null : (ClaimsIdentity)user.Identity;
|
||||||
|
|
||||||
|
foreach (var authType in ListEnabledAuthTypes())
|
||||||
|
{
|
||||||
|
string authString = authType.ToString();
|
||||||
|
if (context.AuthenticationTypes.Contains(authString, StringComparer.Ordinal))
|
||||||
|
{
|
||||||
|
if (identity != null && identity.IsAuthenticated
|
||||||
|
&& string.Equals(authString, identity.AuthenticationType, StringComparison.Ordinal))
|
||||||
|
{
|
||||||
|
context.Authenticated((ClaimsIdentity)user.Identity, properties: null, description: GetDescription(user.Identity.AuthenticationType));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
context.NotAuthenticated(authString, properties: null, description: GetDescription(user.Identity.AuthenticationType));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task AuthenticateAsync(IAuthenticateContext context)
|
||||||
|
{
|
||||||
|
Authenticate(context);
|
||||||
|
return Task.FromResult(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Challenge(IChallengeContext context)
|
||||||
|
{
|
||||||
|
foreach (var authType in ListEnabledAuthTypes())
|
||||||
|
{
|
||||||
|
var authString = authType.ToString();
|
||||||
|
// Not including any auth types means it's a blanket challenge for any auth type.
|
||||||
|
if (context.AuthenticationTypes == null || context.AuthenticationTypes.Count == 0
|
||||||
|
|| context.AuthenticationTypes.Contains(authString, StringComparer.Ordinal))
|
||||||
|
{
|
||||||
|
_customChallenges |= authType;
|
||||||
|
context.Accept(authString, GetDescription(authType.ToString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// A challenge was issued, it overrides any pre-set auth types.
|
||||||
|
_requestContext.AuthenticationChallenges = _customChallenges;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void GetDescriptions(IAuthTypeContext context)
|
||||||
|
{
|
||||||
|
// TODO: Caching, this data doesn't change per request.
|
||||||
|
foreach (var authType in ListEnabledAuthTypes())
|
||||||
|
{
|
||||||
|
context.Accept(GetDescription(authType.ToString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SignIn(ISignInContext context)
|
||||||
|
{
|
||||||
|
// Not supported
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SignOut(ISignOutContext context)
|
||||||
|
{
|
||||||
|
// Not supported
|
||||||
|
}
|
||||||
|
|
||||||
|
private IDictionary<string, object> GetDescription(string authenticationType)
|
||||||
|
{
|
||||||
|
return new Dictionary<string, object>()
|
||||||
|
{
|
||||||
|
{ "AuthenticationType", authenticationType },
|
||||||
|
{ "Caption", "Windows:" + authenticationType },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEnumerable<AuthenticationTypes> ListEnabledAuthTypes()
|
||||||
|
{
|
||||||
|
// Order by strength.
|
||||||
|
if ((_authTypes & AuthenticationTypes.Kerberos) == AuthenticationTypes.Kerberos)
|
||||||
|
{
|
||||||
|
yield return AuthenticationTypes.Kerberos;
|
||||||
|
}
|
||||||
|
if ((_authTypes & AuthenticationTypes.Negotiate) == AuthenticationTypes.Negotiate)
|
||||||
|
{
|
||||||
|
yield return AuthenticationTypes.Negotiate;
|
||||||
|
}
|
||||||
|
if ((_authTypes & AuthenticationTypes.NTLM) == AuthenticationTypes.NTLM)
|
||||||
|
{
|
||||||
|
yield return AuthenticationTypes.NTLM;
|
||||||
|
}
|
||||||
|
/*if ((_authTypes & AuthenticationTypes.Digest) == AuthenticationTypes.Digest)
|
||||||
|
{
|
||||||
|
// TODO:
|
||||||
|
throw new NotImplementedException("Digest challenge generation has not been implemented.");
|
||||||
|
yield return AuthenticationTypes.Digest;
|
||||||
|
}*/
|
||||||
|
if ((_authTypes & AuthenticationTypes.Basic) == AuthenticationTypes.Basic)
|
||||||
|
{
|
||||||
|
yield return AuthenticationTypes.Basic;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -70,6 +70,7 @@ namespace Microsoft.AspNet.Server.WebListener
|
||||||
{
|
{
|
||||||
_requestContext = requestContext;
|
_requestContext = requestContext;
|
||||||
_features = new FeatureCollection();
|
_features = new FeatureCollection();
|
||||||
|
_authHandler = new AuthenticationHandler(requestContext);
|
||||||
PopulateFeatures();
|
PopulateFeatures();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -110,13 +111,10 @@ namespace Microsoft.AspNet.Server.WebListener
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
// _environment.CallCancelled = _cts.Token;
|
|
||||||
// _environment.User = _request.User;
|
|
||||||
// Channel binding
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// Server
|
Server
|
||||||
_environment.Listener = _server;
|
_environment.Listener = _server;
|
||||||
|
Channel binding
|
||||||
_environment.ConnectionId = _request.ConnectionId;
|
_environment.ConnectionId = _request.ConnectionId;
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="AssemblyNeutralAttribute.cs" />
|
<Compile Include="AssemblyNeutralAttribute.cs" />
|
||||||
|
<Compile Include="AuthenticationHandler.cs" />
|
||||||
<Compile Include="FeatureContext.cs" />
|
<Compile Include="FeatureContext.cs" />
|
||||||
<Compile Include="Helpers.cs" />
|
<Compile Include="Helpers.cs" />
|
||||||
<Compile Include="LogHelper.cs" />
|
<Compile Include="LogHelper.cs" />
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,10 @@ namespace Microsoft.Net.Server
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
|
if (_authTypes == AuthenticationTypes.None)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("value", "'None' is not a valid authentication type. Use 'AllowAnonymous' instead.");
|
||||||
|
}
|
||||||
_authTypes = value;
|
_authTypes = value;
|
||||||
SetServerSecurity();
|
SetServerSecurity();
|
||||||
}
|
}
|
||||||
|
|
@ -106,22 +110,25 @@ namespace Microsoft.Net.Server
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: If we're not going to support Digest then this whole list can be pre-computed and cached.
|
internal static IList<string> GenerateChallenges(AuthenticationTypes authTypes)
|
||||||
// consider even pre-serialzing and caching the bytes for the !AllowAnonymous scenario.
|
|
||||||
internal IList<string> GenerateChallenges()
|
|
||||||
{
|
{
|
||||||
IList<string> challenges = new List<string>();
|
IList<string> challenges = new List<string>();
|
||||||
|
|
||||||
|
if (authTypes == AuthenticationTypes.None)
|
||||||
|
{
|
||||||
|
return challenges;
|
||||||
|
}
|
||||||
|
|
||||||
// Order by strength.
|
// Order by strength.
|
||||||
if ((_authTypes & AuthenticationTypes.Kerberos) == AuthenticationTypes.Kerberos)
|
if ((authTypes & AuthenticationTypes.Kerberos) == AuthenticationTypes.Kerberos)
|
||||||
{
|
{
|
||||||
challenges.Add("Kerberos");
|
challenges.Add("Kerberos");
|
||||||
}
|
}
|
||||||
if ((_authTypes & AuthenticationTypes.Negotiate) == AuthenticationTypes.Negotiate)
|
if ((authTypes & AuthenticationTypes.Negotiate) == AuthenticationTypes.Negotiate)
|
||||||
{
|
{
|
||||||
challenges.Add("Negotiate");
|
challenges.Add("Negotiate");
|
||||||
}
|
}
|
||||||
if ((_authTypes & AuthenticationTypes.Ntlm) == AuthenticationTypes.Ntlm)
|
if ((authTypes & AuthenticationTypes.NTLM) == AuthenticationTypes.NTLM)
|
||||||
{
|
{
|
||||||
challenges.Add("NTLM");
|
challenges.Add("NTLM");
|
||||||
}
|
}
|
||||||
|
|
@ -131,7 +138,7 @@ namespace Microsoft.Net.Server
|
||||||
throw new NotImplementedException("Digest challenge generation has not been implemented.");
|
throw new NotImplementedException("Digest challenge generation has not been implemented.");
|
||||||
// challenges.Add("Digest");
|
// challenges.Add("Digest");
|
||||||
}*/
|
}*/
|
||||||
if ((_authTypes & AuthenticationTypes.Basic) == AuthenticationTypes.Basic)
|
if ((authTypes & AuthenticationTypes.Basic) == AuthenticationTypes.Basic)
|
||||||
{
|
{
|
||||||
// TODO: Realm
|
// TODO: Realm
|
||||||
challenges.Add("Basic");
|
challenges.Add("Basic");
|
||||||
|
|
@ -139,9 +146,9 @@ namespace Microsoft.Net.Server
|
||||||
return challenges;
|
return challenges;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void SetAuthenticationChallenge(Response response)
|
internal void SetAuthenticationChallenge(RequestContext context)
|
||||||
{
|
{
|
||||||
IList<string> challenges = GenerateChallenges();
|
IList<string> challenges = GenerateChallenges(context.AuthenticationChallenges);
|
||||||
|
|
||||||
if (challenges.Count > 0)
|
if (challenges.Count > 0)
|
||||||
{
|
{
|
||||||
|
|
@ -149,7 +156,7 @@ namespace Microsoft.Net.Server
|
||||||
// Append to the existing header, if any. Some clients (IE, Chrome) require each challenges to be sent on their own line/header.
|
// Append to the existing header, if any. Some clients (IE, Chrome) require each challenges to be sent on their own line/header.
|
||||||
string[] oldValues;
|
string[] oldValues;
|
||||||
string[] newValues;
|
string[] newValues;
|
||||||
if (response.Headers.TryGetValue(HttpKnownHeaderNames.WWWAuthenticate, out oldValues))
|
if (context.Response.Headers.TryGetValue(HttpKnownHeaderNames.WWWAuthenticate, out oldValues))
|
||||||
{
|
{
|
||||||
newValues = new string[oldValues.Length + challenges.Count];
|
newValues = new string[oldValues.Length + challenges.Count];
|
||||||
Array.Copy(oldValues, newValues, oldValues.Length);
|
Array.Copy(oldValues, newValues, oldValues.Length);
|
||||||
|
|
@ -160,7 +167,7 @@ namespace Microsoft.Net.Server
|
||||||
newValues = new string[challenges.Count];
|
newValues = new string[challenges.Count];
|
||||||
challenges.CopyTo(newValues, 0);
|
challenges.CopyTo(newValues, 0);
|
||||||
}
|
}
|
||||||
response.Headers[HttpKnownHeaderNames.WWWAuthenticate] = newValues;
|
context.Response.Headers[HttpKnownHeaderNames.WWWAuthenticate] = newValues;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -184,10 +191,30 @@ namespace Microsoft.Net.Server
|
||||||
&& requestInfo->pInfo->AuthStatus == UnsafeNclNativeMethods.HttpApi.HTTP_AUTH_STATUS.HttpAuthStatusSuccess)
|
&& requestInfo->pInfo->AuthStatus == UnsafeNclNativeMethods.HttpApi.HTTP_AUTH_STATUS.HttpAuthStatusSuccess)
|
||||||
{
|
{
|
||||||
#if NET45
|
#if NET45
|
||||||
return new WindowsPrincipal(new WindowsIdentity(requestInfo->pInfo->AccessToken));
|
return new WindowsPrincipal(new WindowsIdentity(requestInfo->pInfo->AccessToken,
|
||||||
|
GetAuthTypeFromRequest(requestInfo->pInfo->AuthType).ToString()));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
return new ClaimsPrincipal(new ClaimsIdentity(string.Empty)); // Anonymous / !IsAuthenticated
|
return new ClaimsPrincipal(new ClaimsIdentity()); // Anonymous / !IsAuthenticated
|
||||||
|
}
|
||||||
|
|
||||||
|
private static AuthenticationTypes GetAuthTypeFromRequest(UnsafeNclNativeMethods.HttpApi.HTTP_REQUEST_AUTH_TYPE input)
|
||||||
|
{
|
||||||
|
switch (input)
|
||||||
|
{
|
||||||
|
case UnsafeNclNativeMethods.HttpApi.HTTP_REQUEST_AUTH_TYPE.HttpRequestAuthTypeBasic:
|
||||||
|
return AuthenticationTypes.Basic;
|
||||||
|
// case UnsafeNclNativeMethods.HttpApi.HTTP_REQUEST_AUTH_TYPE.HttpRequestAuthTypeDigest:
|
||||||
|
// return AuthenticationTypes.Digest;
|
||||||
|
case UnsafeNclNativeMethods.HttpApi.HTTP_REQUEST_AUTH_TYPE.HttpRequestAuthTypeNTLM:
|
||||||
|
return AuthenticationTypes.NTLM;
|
||||||
|
case UnsafeNclNativeMethods.HttpApi.HTTP_REQUEST_AUTH_TYPE.HttpRequestAuthTypeNegotiate:
|
||||||
|
return AuthenticationTypes.Negotiate;
|
||||||
|
case UnsafeNclNativeMethods.HttpApi.HTTP_REQUEST_AUTH_TYPE.HttpRequestAuthTypeKerberos:
|
||||||
|
return AuthenticationTypes.Kerberos;
|
||||||
|
default:
|
||||||
|
throw new NotImplementedException(input.ToString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,10 +22,10 @@ namespace Microsoft.Net.Server
|
||||||
[Flags]
|
[Flags]
|
||||||
public enum AuthenticationTypes
|
public enum AuthenticationTypes
|
||||||
{
|
{
|
||||||
// None = 0x0, // None is invalid, use AllowAnonymous (which must have a non-zero value).
|
None = 0x0,
|
||||||
Basic = 0x1,
|
Basic = 0x1,
|
||||||
// Digest = 0x2, // TODO: Verify this is no longer supported by Http.Sys
|
// Digest = 0x2, // TODO: Verify this is no longer supported by Http.Sys
|
||||||
Ntlm = 0x4,
|
NTLM = 0x4,
|
||||||
Negotiate = 0x8,
|
Negotiate = 0x8,
|
||||||
Kerberos = 0x10,
|
Kerberos = 0x10,
|
||||||
AllowAnonymous = 0x1000
|
AllowAnonymous = 0x1000
|
||||||
|
|
|
||||||
|
|
@ -45,14 +45,15 @@ namespace Microsoft.Net.Server
|
||||||
private CancellationTokenSource _requestAbortSource;
|
private CancellationTokenSource _requestAbortSource;
|
||||||
private CancellationToken? _disconnectToken;
|
private CancellationToken? _disconnectToken;
|
||||||
|
|
||||||
internal RequestContext(WebListener httpListener, NativeRequestContext memoryBlob)
|
internal RequestContext(WebListener server, NativeRequestContext memoryBlob)
|
||||||
{
|
{
|
||||||
// TODO: Verbose log
|
// TODO: Verbose log
|
||||||
_server = httpListener;
|
_server = server;
|
||||||
_memoryBlob = memoryBlob;
|
_memoryBlob = memoryBlob;
|
||||||
_request = new Request(this, _memoryBlob);
|
_request = new Request(this, _memoryBlob);
|
||||||
_response = new Response(this);
|
_response = new Response(this);
|
||||||
_request.ReleasePins();
|
_request.ReleasePins();
|
||||||
|
AuthenticationChallenges = server.AuthenticationManager.AuthenticationTypes & ~AuthenticationTypes.AllowAnonymous;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Request Request
|
public Request Request
|
||||||
|
|
@ -129,6 +130,12 @@ namespace Microsoft.Net.Server
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The authentication challengest that will be added to the response if the status code is 401.
|
||||||
|
/// This must be a subset of the AuthenticationTypes enabled on the server.
|
||||||
|
/// </summary>
|
||||||
|
public AuthenticationTypes AuthenticationChallenges { get; set; }
|
||||||
|
|
||||||
public bool IsUpgradableRequest
|
public bool IsUpgradableRequest
|
||||||
{
|
{
|
||||||
get { return _request.IsUpgradable; }
|
get { return _request.IsUpgradable; }
|
||||||
|
|
|
||||||
|
|
@ -471,7 +471,7 @@ namespace Microsoft.Net.Server
|
||||||
// 401
|
// 401
|
||||||
if (StatusCode == (ushort)HttpStatusCode.Unauthorized)
|
if (StatusCode == (ushort)HttpStatusCode.Unauthorized)
|
||||||
{
|
{
|
||||||
RequestContext.Server.AuthenticationManager.SetAuthenticationChallenge(this);
|
RequestContext.Server.AuthenticationManager.SetAuthenticationChallenge(RequestContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
UnsafeNclNativeMethods.HttpApi.HTTP_FLAGS flags = UnsafeNclNativeMethods.HttpApi.HTTP_FLAGS.NONE;
|
UnsafeNclNativeMethods.HttpApi.HTTP_FLAGS flags = UnsafeNclNativeMethods.HttpApi.HTTP_FLAGS.NONE;
|
||||||
|
|
|
||||||
|
|
@ -661,7 +661,8 @@ namespace Microsoft.Net.Server
|
||||||
var requestV2 = (UnsafeNclNativeMethods.HttpApi.HTTP_REQUEST_V2*)requestMemory.RequestBlob;
|
var requestV2 = (UnsafeNclNativeMethods.HttpApi.HTTP_REQUEST_V2*)requestMemory.RequestBlob;
|
||||||
if (!AuthenticationManager.AllowAnonymous && !AuthenticationManager.CheckAuthenticated(requestV2->pRequestInfo))
|
if (!AuthenticationManager.AllowAnonymous && !AuthenticationManager.CheckAuthenticated(requestV2->pRequestInfo))
|
||||||
{
|
{
|
||||||
SendError(requestMemory.RequestBlob->RequestId, HttpStatusCode.Unauthorized, AuthenticationManager.GenerateChallenges());
|
SendError(requestMemory.RequestBlob->RequestId, HttpStatusCode.Unauthorized,
|
||||||
|
AuthenticationManager.GenerateChallenges(AuthenticationManager.AuthenticationTypes));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@
|
||||||
// permissions and limitations under the License.
|
// permissions and limitations under the License.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
@ -31,12 +32,13 @@ namespace Microsoft.AspNet.Server.WebListener
|
||||||
private const string Address = "http://localhost:8080/";
|
private const string Address = "http://localhost:8080/";
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
|
[InlineData(AuthenticationTypes.AllowAnonymous)]
|
||||||
[InlineData(AuthenticationTypes.Kerberos)]
|
[InlineData(AuthenticationTypes.Kerberos)]
|
||||||
[InlineData(AuthenticationTypes.Negotiate)]
|
[InlineData(AuthenticationTypes.Negotiate)]
|
||||||
[InlineData(AuthenticationTypes.Ntlm)]
|
[InlineData(AuthenticationTypes.NTLM)]
|
||||||
// [InlineData(AuthenticationTypes.Digest)]
|
// [InlineData(AuthenticationTypes.Digest)]
|
||||||
[InlineData(AuthenticationTypes.Basic)]
|
[InlineData(AuthenticationTypes.Basic)]
|
||||||
[InlineData(AuthenticationTypes.Kerberos | AuthenticationTypes.Negotiate | AuthenticationTypes.Ntlm | /*AuthenticationTypes.Digest |*/ AuthenticationTypes.Basic)]
|
[InlineData(AuthenticationTypes.Kerberos | AuthenticationTypes.Negotiate | AuthenticationTypes.NTLM | /*AuthenticationTypes.Digest |*/ AuthenticationTypes.Basic)]
|
||||||
public async Task AuthTypes_AllowAnonymous_NoChallenge(AuthenticationTypes authType)
|
public async Task AuthTypes_AllowAnonymous_NoChallenge(AuthenticationTypes authType)
|
||||||
{
|
{
|
||||||
using (Utilities.CreateAuthServer(authType | AuthenticationTypes.AllowAnonymous, env =>
|
using (Utilities.CreateAuthServer(authType | AuthenticationTypes.AllowAnonymous, env =>
|
||||||
|
|
@ -56,7 +58,7 @@ namespace Microsoft.AspNet.Server.WebListener
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData(AuthenticationTypes.Kerberos)]
|
[InlineData(AuthenticationTypes.Kerberos)]
|
||||||
[InlineData(AuthenticationTypes.Negotiate)]
|
[InlineData(AuthenticationTypes.Negotiate)]
|
||||||
[InlineData(AuthenticationTypes.Ntlm)]
|
[InlineData(AuthenticationTypes.NTLM)]
|
||||||
// [InlineData(AuthenticationTypes.Digest)] // TODO: Not implemented
|
// [InlineData(AuthenticationTypes.Digest)] // TODO: Not implemented
|
||||||
[InlineData(AuthenticationTypes.Basic)]
|
[InlineData(AuthenticationTypes.Basic)]
|
||||||
public async Task AuthType_RequireAuth_ChallengesAdded(AuthenticationTypes authType)
|
public async Task AuthType_RequireAuth_ChallengesAdded(AuthenticationTypes authType)
|
||||||
|
|
@ -75,7 +77,7 @@ namespace Microsoft.AspNet.Server.WebListener
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData(AuthenticationTypes.Kerberos)]
|
[InlineData(AuthenticationTypes.Kerberos)]
|
||||||
[InlineData(AuthenticationTypes.Negotiate)]
|
[InlineData(AuthenticationTypes.Negotiate)]
|
||||||
[InlineData(AuthenticationTypes.Ntlm)]
|
[InlineData(AuthenticationTypes.NTLM)]
|
||||||
// [InlineData(AuthenticationTypes.Digest)] // TODO: Not implemented
|
// [InlineData(AuthenticationTypes.Digest)] // TODO: Not implemented
|
||||||
[InlineData(AuthenticationTypes.Basic)]
|
[InlineData(AuthenticationTypes.Basic)]
|
||||||
public async Task AuthType_AllowAnonymousButSpecify401_ChallengesAdded(AuthenticationTypes authType)
|
public async Task AuthType_AllowAnonymousButSpecify401_ChallengesAdded(AuthenticationTypes authType)
|
||||||
|
|
@ -101,7 +103,7 @@ namespace Microsoft.AspNet.Server.WebListener
|
||||||
using (Utilities.CreateAuthServer(
|
using (Utilities.CreateAuthServer(
|
||||||
AuthenticationTypes.Kerberos
|
AuthenticationTypes.Kerberos
|
||||||
| AuthenticationTypes.Negotiate
|
| AuthenticationTypes.Negotiate
|
||||||
| AuthenticationTypes.Ntlm
|
| AuthenticationTypes.NTLM
|
||||||
/* | AuthenticationTypes.Digest TODO: Not implemented */
|
/* | AuthenticationTypes.Digest TODO: Not implemented */
|
||||||
| AuthenticationTypes.Basic
|
| AuthenticationTypes.Basic
|
||||||
| AuthenticationTypes.AllowAnonymous,
|
| AuthenticationTypes.AllowAnonymous,
|
||||||
|
|
@ -123,10 +125,10 @@ namespace Microsoft.AspNet.Server.WebListener
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData(AuthenticationTypes.Kerberos)]
|
[InlineData(AuthenticationTypes.Kerberos)]
|
||||||
[InlineData(AuthenticationTypes.Negotiate)]
|
[InlineData(AuthenticationTypes.Negotiate)]
|
||||||
[InlineData(AuthenticationTypes.Ntlm)]
|
[InlineData(AuthenticationTypes.NTLM)]
|
||||||
// [InlineData(AuthenticationTypes.Digest)] // TODO: Not implemented
|
// [InlineData(AuthenticationTypes.Digest)] // TODO: Not implemented
|
||||||
// [InlineData(AuthenticationTypes.Basic)] // Doesn't work with default creds
|
// [InlineData(AuthenticationTypes.Basic)] // Doesn't work with default creds
|
||||||
[InlineData(AuthenticationTypes.Kerberos | AuthenticationTypes.Negotiate | AuthenticationTypes.Ntlm | /* AuthenticationTypes.Digest |*/ AuthenticationTypes.Basic)]
|
[InlineData(AuthenticationTypes.Kerberos | AuthenticationTypes.Negotiate | AuthenticationTypes.NTLM | /* AuthenticationTypes.Digest |*/ AuthenticationTypes.Basic)]
|
||||||
public async Task AuthTypes_AllowAnonymousButSpecify401_Success(AuthenticationTypes authType)
|
public async Task AuthTypes_AllowAnonymousButSpecify401_Success(AuthenticationTypes authType)
|
||||||
{
|
{
|
||||||
int requestId = 0;
|
int requestId = 0;
|
||||||
|
|
@ -159,10 +161,10 @@ namespace Microsoft.AspNet.Server.WebListener
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData(AuthenticationTypes.Kerberos)]
|
[InlineData(AuthenticationTypes.Kerberos)]
|
||||||
[InlineData(AuthenticationTypes.Negotiate)]
|
[InlineData(AuthenticationTypes.Negotiate)]
|
||||||
[InlineData(AuthenticationTypes.Ntlm)]
|
[InlineData(AuthenticationTypes.NTLM)]
|
||||||
// [InlineData(AuthenticationTypes.Digest)] // TODO: Not implemented
|
// [InlineData(AuthenticationTypes.Digest)] // TODO: Not implemented
|
||||||
// [InlineData(AuthenticationTypes.Basic)] // Doesn't work with default creds
|
// [InlineData(AuthenticationTypes.Basic)] // Doesn't work with default creds
|
||||||
[InlineData(AuthenticationTypes.Kerberos | AuthenticationTypes.Negotiate | AuthenticationTypes.Ntlm | /* AuthenticationTypes.Digest |*/ AuthenticationTypes.Basic)]
|
[InlineData(AuthenticationTypes.Kerberos | AuthenticationTypes.Negotiate | AuthenticationTypes.NTLM | /* AuthenticationTypes.Digest |*/ AuthenticationTypes.Basic)]
|
||||||
public async Task AuthTypes_RequireAuth_Success(AuthenticationTypes authType)
|
public async Task AuthTypes_RequireAuth_Success(AuthenticationTypes authType)
|
||||||
{
|
{
|
||||||
using (Utilities.CreateAuthServer(authType, env =>
|
using (Utilities.CreateAuthServer(authType, env =>
|
||||||
|
|
@ -178,6 +180,216 @@ namespace Microsoft.AspNet.Server.WebListener
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(AuthenticationTypes.AllowAnonymous)]
|
||||||
|
[InlineData(AuthenticationTypes.Kerberos)]
|
||||||
|
[InlineData(AuthenticationTypes.Negotiate)]
|
||||||
|
[InlineData(AuthenticationTypes.NTLM)]
|
||||||
|
// [InlineData(AuthenticationTypes.Digest)]
|
||||||
|
[InlineData(AuthenticationTypes.Basic)]
|
||||||
|
// [InlineData(AuthenticationTypes.Kerberos | AuthenticationTypes.Negotiate | AuthenticationTypes.NTLM | /*AuthenticationTypes.Digest |*/ AuthenticationTypes.Basic)]
|
||||||
|
public async Task AuthTypes_GetSingleDescriptions(AuthenticationTypes authType)
|
||||||
|
{
|
||||||
|
using (Utilities.CreateAuthServer(authType | AuthenticationTypes.AllowAnonymous, env =>
|
||||||
|
{
|
||||||
|
var context = new DefaultHttpContext((IFeatureCollection)env);
|
||||||
|
var resultList = context.GetAuthenticationTypes();
|
||||||
|
if (authType == AuthenticationTypes.AllowAnonymous)
|
||||||
|
{
|
||||||
|
Assert.Equal(0, resultList.Count());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Assert.Equal(1, resultList.Count());
|
||||||
|
var result = resultList.First();
|
||||||
|
Assert.Equal(authType.ToString(), result.AuthenticationType);
|
||||||
|
Assert.Equal("Windows:" + authType.ToString(), result.Caption);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Task.FromResult(0);
|
||||||
|
}))
|
||||||
|
{
|
||||||
|
var response = await SendRequestAsync(Address);
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
Assert.Equal(0, response.Headers.WwwAuthenticate.Count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task AuthTypes_GetMultipleDescriptions()
|
||||||
|
{
|
||||||
|
AuthenticationTypes authType =
|
||||||
|
AuthenticationTypes.Kerberos
|
||||||
|
| AuthenticationTypes.Negotiate
|
||||||
|
| AuthenticationTypes.NTLM
|
||||||
|
| /*AuthenticationTypes.Digest
|
||||||
|
|*/ AuthenticationTypes.Basic;
|
||||||
|
using (Utilities.CreateAuthServer(authType | AuthenticationTypes.AllowAnonymous, env =>
|
||||||
|
{
|
||||||
|
var context = new DefaultHttpContext((IFeatureCollection)env);
|
||||||
|
var resultList = context.GetAuthenticationTypes();
|
||||||
|
Assert.Equal(4, resultList.Count());
|
||||||
|
return Task.FromResult(0);
|
||||||
|
}))
|
||||||
|
{
|
||||||
|
var response = await SendRequestAsync(Address);
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
Assert.Equal(0, response.Headers.WwwAuthenticate.Count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(AuthenticationTypes.Kerberos)]
|
||||||
|
[InlineData(AuthenticationTypes.Negotiate)]
|
||||||
|
[InlineData(AuthenticationTypes.NTLM)]
|
||||||
|
// [InlineData(AuthenticationTypes.Digest)]
|
||||||
|
[InlineData(AuthenticationTypes.Basic)]
|
||||||
|
[InlineData(AuthenticationTypes.Kerberos | AuthenticationTypes.Negotiate | AuthenticationTypes.NTLM | /*AuthenticationTypes.Digest |*/ AuthenticationTypes.Basic)]
|
||||||
|
public async Task AuthTypes_AuthenticateWithNoUser_NoResults(AuthenticationTypes authType)
|
||||||
|
{
|
||||||
|
var authTypeList = authType.ToString().Split(new char[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
using (Utilities.CreateAuthServer(authType | AuthenticationTypes.AllowAnonymous, env =>
|
||||||
|
{
|
||||||
|
var context = new DefaultHttpContext((IFeatureCollection)env);
|
||||||
|
Assert.NotNull(context.User);
|
||||||
|
Assert.False(context.User.Identity.IsAuthenticated);
|
||||||
|
var authResults = context.Authenticate(authTypeList);
|
||||||
|
Assert.False(authResults.Any());
|
||||||
|
return Task.FromResult(0);
|
||||||
|
}))
|
||||||
|
{
|
||||||
|
var response = await SendRequestAsync(Address);
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
Assert.Equal(0, response.Headers.WwwAuthenticate.Count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(AuthenticationTypes.Kerberos)]
|
||||||
|
[InlineData(AuthenticationTypes.Negotiate)]
|
||||||
|
[InlineData(AuthenticationTypes.NTLM)]
|
||||||
|
// [InlineData(AuthenticationTypes.Digest)]
|
||||||
|
// [InlineData(AuthenticationTypes.Basic)] // Doesn't work with default creds
|
||||||
|
[InlineData(AuthenticationTypes.Kerberos | AuthenticationTypes.Negotiate | AuthenticationTypes.NTLM | /*AuthenticationTypes.Digest |*/ AuthenticationTypes.Basic)]
|
||||||
|
public async Task AuthTypes_AuthenticateWithUser_OneResult(AuthenticationTypes authType)
|
||||||
|
{
|
||||||
|
var authTypeList = authType.ToString().Split(new char[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
using (Utilities.CreateAuthServer(authType, env =>
|
||||||
|
{
|
||||||
|
var context = new DefaultHttpContext((IFeatureCollection)env);
|
||||||
|
Assert.NotNull(context.User);
|
||||||
|
Assert.True(context.User.Identity.IsAuthenticated);
|
||||||
|
var authResults = context.Authenticate(authTypeList);
|
||||||
|
Assert.Equal(1, authResults.Count());
|
||||||
|
return Task.FromResult(0);
|
||||||
|
}))
|
||||||
|
{
|
||||||
|
var response = await SendRequestAsync(Address, useDefaultCredentials: true);
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(AuthenticationTypes.Kerberos)]
|
||||||
|
[InlineData(AuthenticationTypes.Negotiate)]
|
||||||
|
[InlineData(AuthenticationTypes.NTLM)]
|
||||||
|
// [InlineData(AuthenticationTypes.Digest)]
|
||||||
|
[InlineData(AuthenticationTypes.Basic)]
|
||||||
|
[InlineData(AuthenticationTypes.Kerberos | AuthenticationTypes.Negotiate | AuthenticationTypes.NTLM | /*AuthenticationTypes.Digest |*/ AuthenticationTypes.Basic)]
|
||||||
|
public async Task AuthTypes_ChallengeWithoutAuthTypes_AllChallengesSent(AuthenticationTypes authType)
|
||||||
|
{
|
||||||
|
var authTypeList = authType.ToString().Split(new char[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
using (Utilities.CreateAuthServer(authType | AuthenticationTypes.AllowAnonymous, env =>
|
||||||
|
{
|
||||||
|
var context = new DefaultHttpContext((IFeatureCollection)env);
|
||||||
|
Assert.NotNull(context.User);
|
||||||
|
Assert.False(context.User.Identity.IsAuthenticated);
|
||||||
|
context.Response.Challenge();
|
||||||
|
return Task.FromResult(0);
|
||||||
|
}))
|
||||||
|
{
|
||||||
|
var response = await SendRequestAsync(Address);
|
||||||
|
Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
|
||||||
|
Assert.Equal(authTypeList.Count(), response.Headers.WwwAuthenticate.Count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(AuthenticationTypes.Kerberos)]
|
||||||
|
[InlineData(AuthenticationTypes.Negotiate)]
|
||||||
|
[InlineData(AuthenticationTypes.NTLM)]
|
||||||
|
// [InlineData(AuthenticationTypes.Digest)]
|
||||||
|
[InlineData(AuthenticationTypes.Basic)]
|
||||||
|
[InlineData(AuthenticationTypes.Kerberos | AuthenticationTypes.Negotiate | AuthenticationTypes.NTLM | /*AuthenticationTypes.Digest |*/ AuthenticationTypes.Basic)]
|
||||||
|
public async Task AuthTypes_ChallengeWithAllAuthTypes_AllChallengesSent(AuthenticationTypes authType)
|
||||||
|
{
|
||||||
|
var authTypeList = authType.ToString().Split(new char[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
using (Utilities.CreateAuthServer(authType | AuthenticationTypes.AllowAnonymous, env =>
|
||||||
|
{
|
||||||
|
var context = new DefaultHttpContext((IFeatureCollection)env);
|
||||||
|
Assert.NotNull(context.User);
|
||||||
|
Assert.False(context.User.Identity.IsAuthenticated);
|
||||||
|
context.Response.Challenge(authTypeList);
|
||||||
|
return Task.FromResult(0);
|
||||||
|
}))
|
||||||
|
{
|
||||||
|
var response = await SendRequestAsync(Address);
|
||||||
|
Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
|
||||||
|
Assert.Equal(authTypeList.Count(), response.Headers.WwwAuthenticate.Count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(AuthenticationTypes.Kerberos)]
|
||||||
|
[InlineData(AuthenticationTypes.Negotiate)]
|
||||||
|
[InlineData(AuthenticationTypes.NTLM)]
|
||||||
|
// [InlineData(AuthenticationTypes.Digest)]
|
||||||
|
[InlineData(AuthenticationTypes.Basic)]
|
||||||
|
public async Task AuthTypes_ChallengeOneAuthType_OneChallengeSent(AuthenticationTypes authType)
|
||||||
|
{
|
||||||
|
var authTypes = AuthenticationTypes.Kerberos | AuthenticationTypes.Negotiate | AuthenticationTypes.NTLM | /*AuthenticationTypes.Digest |*/ AuthenticationTypes.Basic;
|
||||||
|
using (Utilities.CreateAuthServer(authTypes | AuthenticationTypes.AllowAnonymous, env =>
|
||||||
|
{
|
||||||
|
var context = new DefaultHttpContext((IFeatureCollection)env);
|
||||||
|
Assert.NotNull(context.User);
|
||||||
|
Assert.False(context.User.Identity.IsAuthenticated);
|
||||||
|
context.Response.Challenge(authType.ToString());
|
||||||
|
return Task.FromResult(0);
|
||||||
|
}))
|
||||||
|
{
|
||||||
|
var response = await SendRequestAsync(Address);
|
||||||
|
Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
|
||||||
|
Assert.Equal(1, response.Headers.WwwAuthenticate.Count);
|
||||||
|
Assert.Equal(authType.ToString(), response.Headers.WwwAuthenticate.First().Scheme);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(AuthenticationTypes.Kerberos)]
|
||||||
|
[InlineData(AuthenticationTypes.Negotiate)]
|
||||||
|
[InlineData(AuthenticationTypes.NTLM)]
|
||||||
|
// [InlineData(AuthenticationTypes.Digest)]
|
||||||
|
[InlineData(AuthenticationTypes.Basic)]
|
||||||
|
public async Task AuthTypes_ChallengeDisabledAuthType_Error(AuthenticationTypes authType)
|
||||||
|
{
|
||||||
|
var authTypes = AuthenticationTypes.Kerberos | AuthenticationTypes.Negotiate | AuthenticationTypes.NTLM | /*AuthenticationTypes.Digest |*/ AuthenticationTypes.Basic;
|
||||||
|
authTypes = authTypes & ~authType;
|
||||||
|
var authTypeList = authType.ToString().Split(new char[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
using (Utilities.CreateAuthServer(authTypes | AuthenticationTypes.AllowAnonymous, env =>
|
||||||
|
{
|
||||||
|
var context = new DefaultHttpContext((IFeatureCollection)env);
|
||||||
|
Assert.NotNull(context.User);
|
||||||
|
Assert.False(context.User.Identity.IsAuthenticated);
|
||||||
|
Assert.Throws<InvalidOperationException>(() => context.Response.Challenge(authType.ToString()));
|
||||||
|
return Task.FromResult(0);
|
||||||
|
}))
|
||||||
|
{
|
||||||
|
var response = await SendRequestAsync(Address);
|
||||||
|
Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
|
||||||
|
Assert.Equal(0, response.Headers.WwwAuthenticate.Count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async Task<HttpResponseMessage> SendRequestAsync(string uri, bool useDefaultCredentials = false)
|
private async Task<HttpResponseMessage> SendRequestAsync(string uri, bool useDefaultCredentials = false)
|
||||||
{
|
{
|
||||||
HttpClientHandler handler = new HttpClientHandler();
|
HttpClientHandler handler = new HttpClientHandler();
|
||||||
|
|
|
||||||
|
|
@ -16,10 +16,10 @@ namespace Microsoft.Net.Server
|
||||||
[InlineData(AuthenticationTypes.AllowAnonymous)]
|
[InlineData(AuthenticationTypes.AllowAnonymous)]
|
||||||
[InlineData(AuthenticationTypes.Kerberos)]
|
[InlineData(AuthenticationTypes.Kerberos)]
|
||||||
[InlineData(AuthenticationTypes.Negotiate)]
|
[InlineData(AuthenticationTypes.Negotiate)]
|
||||||
[InlineData(AuthenticationTypes.Ntlm)]
|
[InlineData(AuthenticationTypes.NTLM)]
|
||||||
// [InlineData(AuthenticationTypes.Digest)]
|
// [InlineData(AuthenticationTypes.Digest)]
|
||||||
[InlineData(AuthenticationTypes.Basic)]
|
[InlineData(AuthenticationTypes.Basic)]
|
||||||
[InlineData(AuthenticationTypes.Kerberos | AuthenticationTypes.Negotiate | AuthenticationTypes.Ntlm | /*AuthenticationTypes.Digest |*/ AuthenticationTypes.Basic)]
|
[InlineData(AuthenticationTypes.Kerberos | AuthenticationTypes.Negotiate | AuthenticationTypes.NTLM | /*AuthenticationTypes.Digest |*/ AuthenticationTypes.Basic)]
|
||||||
public async Task AuthTypes_AllowAnonymous_NoChallenge(AuthenticationTypes authType)
|
public async Task AuthTypes_AllowAnonymous_NoChallenge(AuthenticationTypes authType)
|
||||||
{
|
{
|
||||||
using (var server = Utilities.CreateAuthServer(authType | AuthenticationTypes.AllowAnonymous))
|
using (var server = Utilities.CreateAuthServer(authType | AuthenticationTypes.AllowAnonymous))
|
||||||
|
|
@ -29,6 +29,14 @@ namespace Microsoft.Net.Server
|
||||||
var context = await server.GetContextAsync();
|
var context = await server.GetContextAsync();
|
||||||
Assert.NotNull(context.User);
|
Assert.NotNull(context.User);
|
||||||
Assert.False(context.User.Identity.IsAuthenticated);
|
Assert.False(context.User.Identity.IsAuthenticated);
|
||||||
|
if (authType == AuthenticationTypes.AllowAnonymous)
|
||||||
|
{
|
||||||
|
Assert.Equal(AuthenticationTypes.None, context.AuthenticationChallenges);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Assert.Equal(authType, context.AuthenticationChallenges);
|
||||||
|
}
|
||||||
context.Dispose();
|
context.Dispose();
|
||||||
|
|
||||||
var response = await responseTask;
|
var response = await responseTask;
|
||||||
|
|
@ -40,7 +48,7 @@ namespace Microsoft.Net.Server
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData(AuthenticationTypes.Kerberos)]
|
[InlineData(AuthenticationTypes.Kerberos)]
|
||||||
[InlineData(AuthenticationTypes.Negotiate)]
|
[InlineData(AuthenticationTypes.Negotiate)]
|
||||||
[InlineData(AuthenticationTypes.Ntlm)]
|
[InlineData(AuthenticationTypes.NTLM)]
|
||||||
// [InlineData(AuthenticationType.Digest)] // TODO: Not implemented
|
// [InlineData(AuthenticationType.Digest)] // TODO: Not implemented
|
||||||
[InlineData(AuthenticationTypes.Basic)]
|
[InlineData(AuthenticationTypes.Basic)]
|
||||||
public async Task AuthType_RequireAuth_ChallengesAdded(AuthenticationTypes authType)
|
public async Task AuthType_RequireAuth_ChallengesAdded(AuthenticationTypes authType)
|
||||||
|
|
@ -60,7 +68,7 @@ namespace Microsoft.Net.Server
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData(AuthenticationTypes.Kerberos)]
|
[InlineData(AuthenticationTypes.Kerberos)]
|
||||||
[InlineData(AuthenticationTypes.Negotiate)]
|
[InlineData(AuthenticationTypes.Negotiate)]
|
||||||
[InlineData(AuthenticationTypes.Ntlm)]
|
[InlineData(AuthenticationTypes.NTLM)]
|
||||||
// [InlineData(AuthenticationTypes.Digest)] // TODO: Not implemented
|
// [InlineData(AuthenticationTypes.Digest)] // TODO: Not implemented
|
||||||
[InlineData(AuthenticationTypes.Basic)]
|
[InlineData(AuthenticationTypes.Basic)]
|
||||||
public async Task AuthType_AllowAnonymousButSpecify401_ChallengesAdded(AuthenticationTypes authType)
|
public async Task AuthType_AllowAnonymousButSpecify401_ChallengesAdded(AuthenticationTypes authType)
|
||||||
|
|
@ -72,6 +80,7 @@ namespace Microsoft.Net.Server
|
||||||
var context = await server.GetContextAsync();
|
var context = await server.GetContextAsync();
|
||||||
Assert.NotNull(context.User);
|
Assert.NotNull(context.User);
|
||||||
Assert.False(context.User.Identity.IsAuthenticated);
|
Assert.False(context.User.Identity.IsAuthenticated);
|
||||||
|
Assert.Equal(authType, context.AuthenticationChallenges);
|
||||||
context.Response.StatusCode = 401;
|
context.Response.StatusCode = 401;
|
||||||
context.Dispose();
|
context.Dispose();
|
||||||
|
|
||||||
|
|
@ -84,19 +93,20 @@ namespace Microsoft.Net.Server
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task MultipleAuthTypes_AllowAnonymousButSpecify401_ChallengesAdded()
|
public async Task MultipleAuthTypes_AllowAnonymousButSpecify401_ChallengesAdded()
|
||||||
{
|
{
|
||||||
using (var server = Utilities.CreateAuthServer(
|
AuthenticationTypes authType =
|
||||||
AuthenticationTypes.Kerberos
|
AuthenticationTypes.Kerberos
|
||||||
| AuthenticationTypes.Negotiate
|
| AuthenticationTypes.Negotiate
|
||||||
| AuthenticationTypes.Ntlm
|
| AuthenticationTypes.NTLM
|
||||||
/* | AuthenticationTypes.Digest TODO: Not implemented */
|
/* | AuthenticationTypes.Digest TODO: Not implemented */
|
||||||
| AuthenticationTypes.Basic
|
| AuthenticationTypes.Basic;
|
||||||
| AuthenticationTypes.AllowAnonymous))
|
using (var server = Utilities.CreateAuthServer(authType | AuthenticationTypes.AllowAnonymous))
|
||||||
{
|
{
|
||||||
Task<HttpResponseMessage> responseTask = SendRequestAsync(Address);
|
Task<HttpResponseMessage> responseTask = SendRequestAsync(Address);
|
||||||
|
|
||||||
var context = await server.GetContextAsync();
|
var context = await server.GetContextAsync();
|
||||||
Assert.NotNull(context.User);
|
Assert.NotNull(context.User);
|
||||||
Assert.False(context.User.Identity.IsAuthenticated);
|
Assert.False(context.User.Identity.IsAuthenticated);
|
||||||
|
Assert.Equal(authType, context.AuthenticationChallenges);
|
||||||
context.Response.StatusCode = 401;
|
context.Response.StatusCode = 401;
|
||||||
context.Dispose();
|
context.Dispose();
|
||||||
|
|
||||||
|
|
@ -109,10 +119,10 @@ namespace Microsoft.Net.Server
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData(AuthenticationTypes.Kerberos)]
|
[InlineData(AuthenticationTypes.Kerberos)]
|
||||||
[InlineData(AuthenticationTypes.Negotiate)]
|
[InlineData(AuthenticationTypes.Negotiate)]
|
||||||
[InlineData(AuthenticationTypes.Ntlm)]
|
[InlineData(AuthenticationTypes.NTLM)]
|
||||||
// [InlineData(AuthenticationTypes.Digest)] // TODO: Not implemented
|
// [InlineData(AuthenticationTypes.Digest)] // TODO: Not implemented
|
||||||
// [InlineData(AuthenticationTypes.Basic)] // Doesn't work with default creds
|
// [InlineData(AuthenticationTypes.Basic)] // Doesn't work with default creds
|
||||||
[InlineData(AuthenticationTypes.Kerberos | AuthenticationTypes.Negotiate | AuthenticationTypes.Ntlm | /*AuthenticationType.Digest |*/ AuthenticationTypes.Basic)]
|
[InlineData(AuthenticationTypes.Kerberos | AuthenticationTypes.Negotiate | AuthenticationTypes.NTLM | /*AuthenticationType.Digest |*/ AuthenticationTypes.Basic)]
|
||||||
public async Task AuthTypes_AllowAnonymousButSpecify401_Success(AuthenticationTypes authType)
|
public async Task AuthTypes_AllowAnonymousButSpecify401_Success(AuthenticationTypes authType)
|
||||||
{
|
{
|
||||||
using (var server = Utilities.CreateAuthServer(authType | AuthenticationTypes.AllowAnonymous))
|
using (var server = Utilities.CreateAuthServer(authType | AuthenticationTypes.AllowAnonymous))
|
||||||
|
|
@ -122,12 +132,14 @@ namespace Microsoft.Net.Server
|
||||||
var context = await server.GetContextAsync();
|
var context = await server.GetContextAsync();
|
||||||
Assert.NotNull(context.User);
|
Assert.NotNull(context.User);
|
||||||
Assert.False(context.User.Identity.IsAuthenticated);
|
Assert.False(context.User.Identity.IsAuthenticated);
|
||||||
|
Assert.Equal(authType, context.AuthenticationChallenges);
|
||||||
context.Response.StatusCode = 401;
|
context.Response.StatusCode = 401;
|
||||||
context.Dispose();
|
context.Dispose();
|
||||||
|
|
||||||
context = await server.GetContextAsync();
|
context = await server.GetContextAsync();
|
||||||
Assert.NotNull(context.User);
|
Assert.NotNull(context.User);
|
||||||
Assert.True(context.User.Identity.IsAuthenticated);
|
Assert.True(context.User.Identity.IsAuthenticated);
|
||||||
|
Assert.Equal(authType, context.AuthenticationChallenges);
|
||||||
context.Dispose();
|
context.Dispose();
|
||||||
|
|
||||||
var response = await responseTask;
|
var response = await responseTask;
|
||||||
|
|
@ -138,10 +150,10 @@ namespace Microsoft.Net.Server
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData(AuthenticationTypes.Kerberos)]
|
[InlineData(AuthenticationTypes.Kerberos)]
|
||||||
[InlineData(AuthenticationTypes.Negotiate)]
|
[InlineData(AuthenticationTypes.Negotiate)]
|
||||||
[InlineData(AuthenticationTypes.Ntlm)]
|
[InlineData(AuthenticationTypes.NTLM)]
|
||||||
// [InlineData(AuthenticationTypes.Digest)] // TODO: Not implemented
|
// [InlineData(AuthenticationTypes.Digest)] // TODO: Not implemented
|
||||||
// [InlineData(AuthenticationTypes.Basic)] // Doesn't work with default creds
|
// [InlineData(AuthenticationTypes.Basic)] // Doesn't work with default creds
|
||||||
[InlineData(AuthenticationTypes.Kerberos | AuthenticationTypes.Negotiate | AuthenticationTypes.Ntlm | /*AuthenticationType.Digest |*/ AuthenticationTypes.Basic)]
|
[InlineData(AuthenticationTypes.Kerberos | AuthenticationTypes.Negotiate | AuthenticationTypes.NTLM | /*AuthenticationType.Digest |*/ AuthenticationTypes.Basic)]
|
||||||
public async Task AuthTypes_RequireAuth_Success(AuthenticationTypes authType)
|
public async Task AuthTypes_RequireAuth_Success(AuthenticationTypes authType)
|
||||||
{
|
{
|
||||||
using (var server = Utilities.CreateAuthServer(authType))
|
using (var server = Utilities.CreateAuthServer(authType))
|
||||||
|
|
@ -151,6 +163,7 @@ namespace Microsoft.Net.Server
|
||||||
var context = await server.GetContextAsync();
|
var context = await server.GetContextAsync();
|
||||||
Assert.NotNull(context.User);
|
Assert.NotNull(context.User);
|
||||||
Assert.True(context.User.Identity.IsAuthenticated);
|
Assert.True(context.User.Identity.IsAuthenticated);
|
||||||
|
Assert.Equal(authType, context.AuthenticationChallenges);
|
||||||
context.Dispose();
|
context.Dispose();
|
||||||
|
|
||||||
var response = await responseTask;
|
var response = await responseTask;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue