Purge old tests.
This commit is contained in:
parent
b43c27763d
commit
93a88af467
|
|
@ -1,64 +0,0 @@
|
|||
// 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="DenyAnonymous.cs" company="Katana contributors">
|
||||
// Copyright 2011-2012 Katana contributors
|
||||
// </copyright>
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Principal;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows.Tests
|
||||
{
|
||||
using AppFunc = Func<IDictionary<string, object>, Task>;
|
||||
|
||||
// This middleware can be placed at the end of a chain of pass-through auth schemes if at least one type of auth is required.
|
||||
public class DenyAnonymous
|
||||
{
|
||||
private readonly AppFunc _nextApp;
|
||||
|
||||
public DenyAnonymous(AppFunc nextApp)
|
||||
{
|
||||
_nextApp = nextApp;
|
||||
}
|
||||
|
||||
public async Task Invoke(IDictionary<string, object> env)
|
||||
{
|
||||
if (env.Get<IPrincipal>("server.User") == null)
|
||||
{
|
||||
env["owin.ResponseStatusCode"] = 401;
|
||||
return;
|
||||
}
|
||||
|
||||
await _nextApp(env);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
// 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="DictionaryExtensions.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace System.Collections.Generic
|
||||
{
|
||||
internal static class DictionaryExtensions
|
||||
{
|
||||
internal static void Append(this IDictionary<string, string[]> dictionary, string key, string value)
|
||||
{
|
||||
string[] orriginalValues;
|
||||
if (dictionary.TryGetValue(key, out orriginalValues))
|
||||
{
|
||||
string[] newValues = new string[orriginalValues.Length + 1];
|
||||
orriginalValues.CopyTo(newValues, 0);
|
||||
newValues[newValues.Length - 1] = value;
|
||||
dictionary[key] = newValues;
|
||||
}
|
||||
else
|
||||
{
|
||||
dictionary[key] = new string[] { value };
|
||||
}
|
||||
}
|
||||
|
||||
internal static string Get(this IDictionary<string, string[]> dictionary, string key)
|
||||
{
|
||||
string[] values;
|
||||
if (dictionary.TryGetValue(key, out values))
|
||||
{
|
||||
return string.Join(", ", values);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
internal static T Get<T>(this IDictionary<string, object> dictionary, string key, T fallback = default(T))
|
||||
{
|
||||
object values;
|
||||
if (dictionary.TryGetValue(key, out values))
|
||||
{
|
||||
return (T)values;
|
||||
}
|
||||
return fallback;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,261 +0,0 @@
|
|||
// 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="DigestTests.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Security.Authentication.ExtendedProtection;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Server.WebListener;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows.Tests
|
||||
{
|
||||
using AppFunc = Func<IDictionary<string, object>, Task>;
|
||||
|
||||
public class DigestTests
|
||||
{
|
||||
private const string Address = "http://localhost:8080/";
|
||||
private const string SecureAddress = "https://localhost:9090/";
|
||||
private const int DefaultStatusCode = 201;
|
||||
|
||||
[Fact]
|
||||
public async Task Digest_PartialMatch_PassedThrough()
|
||||
{
|
||||
WindowsAuthMiddleware windowsAuth = new WindowsAuthMiddleware(SimpleApp);
|
||||
IDictionary<string, object> emptyEnv = CreateEmptyRequest("Authorization", "Digestion blablabla");
|
||||
await windowsAuth.Invoke(emptyEnv);
|
||||
|
||||
Assert.Equal(DefaultStatusCode, emptyEnv.Get<int>("owin.ResponseStatusCode"));
|
||||
var responseHeaders = emptyEnv.Get<IDictionary<string, string[]>>("owin.ResponseHeaders");
|
||||
Assert.Equal(0, responseHeaders.Count);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Digest_BadData_400()
|
||||
{
|
||||
WindowsAuthMiddleware windowsAuth = new WindowsAuthMiddleware(SimpleApp);
|
||||
IDictionary<string, object> emptyEnv = CreateEmptyRequest("Authorization", "Digest blablabla");
|
||||
await windowsAuth.Invoke(emptyEnv);
|
||||
|
||||
Assert.Equal(400, emptyEnv.Get<int>("owin.ResponseStatusCode"));
|
||||
var responseHeaders = emptyEnv.Get<IDictionary<string, string[]>>("owin.ResponseHeaders");
|
||||
Assert.Equal(0, responseHeaders.Count);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Digest_AppSets401_401WithChallenge()
|
||||
{
|
||||
WindowsAuthMiddleware windowsAuth = new WindowsAuthMiddleware(new DenyAnonymous(SimpleApp).Invoke);
|
||||
windowsAuth.AuthenticationSchemes = AuthTypes.Digest;
|
||||
IDictionary<string, object> emptyEnv = CreateEmptyRequest();
|
||||
await windowsAuth.Invoke(emptyEnv);
|
||||
FireOnSendingHeadersActions(emptyEnv);
|
||||
|
||||
Assert.Equal(401, emptyEnv.Get<int>("owin.ResponseStatusCode"));
|
||||
var responseHeaders = emptyEnv.Get<IDictionary<string, string[]>>("owin.ResponseHeaders");
|
||||
Assert.Equal(1, responseHeaders.Count);
|
||||
Assert.NotNull(responseHeaders.Get("www-authenticate"));
|
||||
Assert.True(responseHeaders.Get("www-authenticate").StartsWith("Digest "));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Digest_CbtOptionalButNotPresent_401WithChallenge()
|
||||
{
|
||||
WindowsAuthMiddleware windowsAuth = new WindowsAuthMiddleware(new DenyAnonymous(SimpleApp).Invoke);
|
||||
windowsAuth.AuthenticationSchemes = AuthTypes.Digest;
|
||||
windowsAuth.ExtendedProtectionPolicy = new ExtendedProtectionPolicy(PolicyEnforcement.WhenSupported);
|
||||
IDictionary<string, object> emptyEnv = CreateEmptyRequest();
|
||||
emptyEnv["owin.RequestScheme"] = "https";
|
||||
await windowsAuth.Invoke(emptyEnv);
|
||||
FireOnSendingHeadersActions(emptyEnv);
|
||||
|
||||
Assert.Equal(401, emptyEnv.Get<int>("owin.ResponseStatusCode"));
|
||||
var responseHeaders = emptyEnv.Get<IDictionary<string, string[]>>("owin.ResponseHeaders");
|
||||
Assert.Equal(0, responseHeaders.Count);
|
||||
Assert.Null(responseHeaders.Get("www-authenticate"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Digest_CbtRequiredButNotPresent_400()
|
||||
{
|
||||
WindowsAuthMiddleware windowsAuth = new WindowsAuthMiddleware(new DenyAnonymous(SimpleApp).Invoke);
|
||||
windowsAuth.AuthenticationSchemes = AuthTypes.Digest;
|
||||
windowsAuth.ExtendedProtectionPolicy = new ExtendedProtectionPolicy(PolicyEnforcement.Always);
|
||||
IDictionary<string, object> emptyEnv = CreateEmptyRequest();
|
||||
emptyEnv["owin.RequestScheme"] = "https";
|
||||
await windowsAuth.Invoke(emptyEnv);
|
||||
FireOnSendingHeadersActions(emptyEnv);
|
||||
|
||||
Assert.Equal(401, emptyEnv.Get<int>("owin.ResponseStatusCode"));
|
||||
var responseHeaders = emptyEnv.Get<IDictionary<string, string[]>>("owin.ResponseHeaders");
|
||||
Assert.Equal(0, responseHeaders.Count);
|
||||
Assert.Null(responseHeaders.Get("www-authenticate"));
|
||||
}
|
||||
|
||||
[Fact(Skip = "Broken")]
|
||||
public async Task Digest_ClientAuthenticates_Success()
|
||||
{
|
||||
WindowsAuthMiddleware windowsAuth = new WindowsAuthMiddleware(new DenyAnonymous(SimpleApp).Invoke);
|
||||
windowsAuth.AuthenticationSchemes = AuthTypes.Digest;
|
||||
|
||||
using (CreateServer(windowsAuth.Invoke))
|
||||
{
|
||||
HttpResponseMessage response = await SendAuthRequestAsync(Address);
|
||||
Assert.Equal(DefaultStatusCode, (int)response.StatusCode);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact(Skip = "Broken")]
|
||||
public async Task Digest_ClientAuthenticatesMultipleTimes_Success()
|
||||
{
|
||||
WindowsAuthMiddleware windowsAuth = new WindowsAuthMiddleware(new DenyAnonymous(SimpleApp).Invoke);
|
||||
windowsAuth.AuthenticationSchemes = AuthTypes.Digest;
|
||||
|
||||
using (CreateServer(windowsAuth.Invoke))
|
||||
{
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
HttpResponseMessage response = await SendAuthRequestAsync(Address);
|
||||
Assert.Equal(DefaultStatusCode, (int)response.StatusCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Digest_AnonmousClient_401()
|
||||
{
|
||||
WindowsAuthMiddleware windowsAuth = new WindowsAuthMiddleware(new DenyAnonymous(SimpleApp).Invoke);
|
||||
windowsAuth.AuthenticationSchemes = AuthTypes.Digest;
|
||||
|
||||
using (CreateServer(windowsAuth.Invoke))
|
||||
{
|
||||
HttpResponseMessage response = await SendRequestAsync(Address);
|
||||
Assert.Equal(401, (int)response.StatusCode);
|
||||
Assert.True(response.Headers.WwwAuthenticate.ToString().StartsWith("Digest "));
|
||||
}
|
||||
}
|
||||
|
||||
[Fact(Skip = "Broken")]
|
||||
public async Task Digest_ClientAuthenticatesWithCbt_Success()
|
||||
{
|
||||
WindowsAuthMiddleware windowsAuth = new WindowsAuthMiddleware(new DenyAnonymous(SimpleApp).Invoke);
|
||||
windowsAuth.AuthenticationSchemes = AuthTypes.Digest;
|
||||
windowsAuth.ExtendedProtectionPolicy = new ExtendedProtectionPolicy(PolicyEnforcement.Always);
|
||||
|
||||
using (CreateSecureServer(windowsAuth.Invoke))
|
||||
{
|
||||
HttpResponseMessage response = await SendAuthRequestAsync(SecureAddress);
|
||||
Assert.Equal(DefaultStatusCode, (int)response.StatusCode);
|
||||
}
|
||||
}
|
||||
|
||||
private IDictionary<string, object> CreateEmptyRequest(string header = null, string value = null)
|
||||
{
|
||||
IDictionary<string, object> env = new Dictionary<string, object>();
|
||||
var requestHeaders = new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase);
|
||||
env["owin.RequestHeaders"] = requestHeaders;
|
||||
if (header != null)
|
||||
{
|
||||
requestHeaders[header] = new string[] { value };
|
||||
}
|
||||
env["owin.ResponseHeaders"] = new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
var onSendingHeadersActions = new List<Tuple<Action<object>, object>>();
|
||||
env["server.OnSendingHeaders"] = new Action<Action<object>, object>(
|
||||
(a, b) => onSendingHeadersActions.Add(new Tuple<Action<object>, object>(a, b)));
|
||||
|
||||
env["test.OnSendingHeadersActions"] = onSendingHeadersActions;
|
||||
return env;
|
||||
}
|
||||
|
||||
private void FireOnSendingHeadersActions(IDictionary<string, object> env)
|
||||
{
|
||||
var onSendingHeadersActions = env.Get<IList<Tuple<Action<object>, object>>>("test.OnSendingHeadersActions");
|
||||
foreach (var actionPair in onSendingHeadersActions.Reverse())
|
||||
{
|
||||
actionPair.Item1(actionPair.Item2);
|
||||
}
|
||||
}
|
||||
|
||||
private IDisposable CreateServer(AppFunc app)
|
||||
{
|
||||
IDictionary<string, object> properties = new Dictionary<string, object>();
|
||||
IList<IDictionary<string, object>> addresses = new List<IDictionary<string, object>>();
|
||||
properties["host.Addresses"] = addresses;
|
||||
|
||||
IDictionary<string, object> address = new Dictionary<string, object>();
|
||||
addresses.Add(address);
|
||||
|
||||
address["scheme"] = "http";
|
||||
address["host"] = "localhost";
|
||||
address["port"] = "8080";
|
||||
address["path"] = string.Empty;
|
||||
|
||||
return OwinServerFactory.Create(app, properties);
|
||||
}
|
||||
|
||||
private IDisposable CreateSecureServer(AppFunc app)
|
||||
{
|
||||
IDictionary<string, object> properties = new Dictionary<string, object>();
|
||||
IList<IDictionary<string, object>> addresses = new List<IDictionary<string, object>>();
|
||||
properties["host.Addresses"] = addresses;
|
||||
|
||||
IDictionary<string, object> address = new Dictionary<string, object>();
|
||||
addresses.Add(address);
|
||||
|
||||
address["scheme"] = "https";
|
||||
address["host"] = "localhost";
|
||||
address["port"] = "9090";
|
||||
address["path"] = string.Empty;
|
||||
|
||||
return OwinServerFactory.Create(app, properties);
|
||||
}
|
||||
|
||||
private async Task<HttpResponseMessage> SendRequestAsync(string uri)
|
||||
{
|
||||
using (HttpClient client = new HttpClient())
|
||||
{
|
||||
return await client.GetAsync(uri);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<HttpResponseMessage> SendAuthRequestAsync(string uri)
|
||||
{
|
||||
WebRequestHandler handler = new WebRequestHandler();
|
||||
handler.UseDefaultCredentials = true;
|
||||
handler.ServerCertificateValidationCallback = (a, b, c, d) => true;
|
||||
using (HttpClient client = new HttpClient(handler))
|
||||
{
|
||||
return await client.GetAsync(uri);
|
||||
}
|
||||
}
|
||||
|
||||
private Task SimpleApp(IDictionary<string, object> env)
|
||||
{
|
||||
env["owin.ResponseStatusCode"] = DefaultStatusCode;
|
||||
return Task.FromResult<object>(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,278 +0,0 @@
|
|||
// 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="NegotiateTests.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Security.Authentication.ExtendedProtection;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Server.WebListener;
|
||||
using Xunit;
|
||||
using Xunit.Extensions;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows.Tests
|
||||
{
|
||||
using AppFunc = Func<IDictionary<string, object>, Task>;
|
||||
|
||||
public class NegotiateTests
|
||||
{
|
||||
private const string Address = "http://localhost:8080/";
|
||||
private const string SecureAddress = "https://localhost:9090/";
|
||||
private const int DefaultStatusCode = 201;
|
||||
|
||||
[Theory]
|
||||
[InlineData("Negotiate")]
|
||||
[InlineData("NTLM")]
|
||||
public async Task Negotiate_PartialMatch_PassedThrough(string package)
|
||||
{
|
||||
WindowsAuthMiddleware windowsAuth = new WindowsAuthMiddleware(SimpleApp);
|
||||
IDictionary<string, object> emptyEnv = CreateEmptyRequest("Authorization", package + "ion blablabla");
|
||||
await windowsAuth.Invoke(emptyEnv);
|
||||
|
||||
Assert.Equal(DefaultStatusCode, emptyEnv.Get<int>("owin.ResponseStatusCode"));
|
||||
var responseHeaders = emptyEnv.Get<IDictionary<string, string[]>>("owin.ResponseHeaders");
|
||||
Assert.Equal(0, responseHeaders.Count);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("Negotiate")]
|
||||
[InlineData("NTLM")]
|
||||
public async Task Negotiate_BadData_400(string package)
|
||||
{
|
||||
WindowsAuthMiddleware windowsAuth = new WindowsAuthMiddleware(SimpleApp);
|
||||
IDictionary<string, object> emptyEnv = CreateEmptyRequest("Authorization", package + " blablabla");
|
||||
await windowsAuth.Invoke(emptyEnv);
|
||||
|
||||
Assert.Equal(400, emptyEnv.Get<int>("owin.ResponseStatusCode"));
|
||||
var responseHeaders = emptyEnv.Get<IDictionary<string, string[]>>("owin.ResponseHeaders");
|
||||
Assert.Equal(0, responseHeaders.Count);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("Negotiate")]
|
||||
[InlineData("NTLM")]
|
||||
public async Task Negotiate_AppSets401_401WithChallenge(string package)
|
||||
{
|
||||
WindowsAuthMiddleware windowsAuth = new WindowsAuthMiddleware(SimpleApp401);
|
||||
windowsAuth.AuthenticationSchemes = (AuthTypes)Enum.Parse(typeof(AuthTypes), package, true);
|
||||
IDictionary<string, object> emptyEnv = CreateEmptyRequest();
|
||||
await windowsAuth.Invoke(emptyEnv);
|
||||
FireOnSendingHeadersActions(emptyEnv);
|
||||
|
||||
Assert.Equal(401, emptyEnv.Get<int>("owin.ResponseStatusCode"));
|
||||
var responseHeaders = emptyEnv.Get<IDictionary<string, string[]>>("owin.ResponseHeaders");
|
||||
Assert.Equal(1, responseHeaders.Count);
|
||||
Assert.NotNull(responseHeaders.Get("www-authenticate"));
|
||||
Assert.Equal(package, responseHeaders.Get("www-authenticate"));
|
||||
}
|
||||
|
||||
[Theory(Skip = "Broken")]
|
||||
[InlineData("Negotiate")]
|
||||
[InlineData("NTLM")]
|
||||
public async Task Negotiate_ClientAuthenticates_Success(string package)
|
||||
{
|
||||
WindowsAuthMiddleware windowsAuth = new WindowsAuthMiddleware(new DenyAnonymous(SimpleApp).Invoke);
|
||||
windowsAuth.AuthenticationSchemes = (AuthTypes)Enum.Parse(typeof(AuthTypes), package, true);
|
||||
|
||||
using (CreateServer(windowsAuth.Invoke))
|
||||
{
|
||||
HttpResponseMessage response = await SendAuthRequestAsync(Address);
|
||||
Assert.Equal(DefaultStatusCode, (int)response.StatusCode);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory(Skip = "Broken")]
|
||||
[InlineData("Negotiate")]
|
||||
[InlineData("NTLM")]
|
||||
public async Task Negotiate_ClientAuthenticatesMultipleTimes_Success(string package)
|
||||
{
|
||||
WindowsAuthMiddleware windowsAuth = new WindowsAuthMiddleware(new DenyAnonymous(SimpleApp).Invoke);
|
||||
windowsAuth.AuthenticationSchemes = (AuthTypes)Enum.Parse(typeof(AuthTypes), package, true);
|
||||
|
||||
using (CreateServer(windowsAuth.Invoke))
|
||||
{
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
HttpResponseMessage response = await SendAuthRequestAsync(Address);
|
||||
Assert.Equal(DefaultStatusCode, (int)response.StatusCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("Negotiate")]
|
||||
[InlineData("NTLM")]
|
||||
public async Task Negotiate_AnonmousClient_401(string package)
|
||||
{
|
||||
WindowsAuthMiddleware windowsAuth = new WindowsAuthMiddleware(new DenyAnonymous(SimpleApp).Invoke);
|
||||
windowsAuth.AuthenticationSchemes = (AuthTypes)Enum.Parse(typeof(AuthTypes), package, true);
|
||||
|
||||
using (CreateServer(windowsAuth.Invoke))
|
||||
{
|
||||
HttpResponseMessage response = await SendRequestAsync(Address);
|
||||
Assert.Equal(401, (int)response.StatusCode);
|
||||
Assert.Equal(package, response.Headers.WwwAuthenticate.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[Fact(Skip = "Broken")]
|
||||
public async Task UnsafeSharedNTLM_AuthenticatedClient_Success()
|
||||
{
|
||||
WindowsAuthMiddleware windowsAuth = new WindowsAuthMiddleware(new DenyAnonymous(SimpleApp).Invoke);
|
||||
windowsAuth.AuthenticationSchemes = AuthTypes.Ntlm;
|
||||
windowsAuth.UnsafeConnectionNtlmAuthentication = true;
|
||||
|
||||
using (CreateServer(windowsAuth.Invoke))
|
||||
{
|
||||
WebRequestHandler handler = new WebRequestHandler();
|
||||
CredentialCache cache = new CredentialCache();
|
||||
cache.Add(new Uri(Address), "NTLM", CredentialCache.DefaultNetworkCredentials);
|
||||
handler.Credentials = cache;
|
||||
handler.UnsafeAuthenticatedConnectionSharing = true;
|
||||
using (HttpClient client = new HttpClient(handler))
|
||||
{
|
||||
HttpResponseMessage response = await client.GetAsync(Address);
|
||||
Assert.Equal(DefaultStatusCode, (int)response.StatusCode);
|
||||
response.EnsureSuccessStatusCode();
|
||||
|
||||
// Remove the credentials before try two just to prove they aren't used.
|
||||
cache.Remove(new Uri(Address), "NTLM");
|
||||
response = await client.GetAsync(Address);
|
||||
Assert.Equal(DefaultStatusCode, (int)response.StatusCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Theory(Skip = "Broken")]
|
||||
[InlineData("Negotiate")]
|
||||
[InlineData("NTLM")]
|
||||
public async Task Negotiate_ClientAuthenticatesWithCbt_Success(string package)
|
||||
{
|
||||
WindowsAuthMiddleware windowsAuth = new WindowsAuthMiddleware(new DenyAnonymous(SimpleApp).Invoke);
|
||||
windowsAuth.AuthenticationSchemes = (AuthTypes)Enum.Parse(typeof(AuthTypes), package, true);
|
||||
windowsAuth.ExtendedProtectionPolicy = new ExtendedProtectionPolicy(PolicyEnforcement.Always);
|
||||
|
||||
using (CreateSecureServer(windowsAuth.Invoke))
|
||||
{
|
||||
HttpResponseMessage response = await SendAuthRequestAsync(SecureAddress);
|
||||
Assert.Equal(DefaultStatusCode, (int)response.StatusCode);
|
||||
}
|
||||
}
|
||||
|
||||
private IDictionary<string, object> CreateEmptyRequest(string header = null, string value = null, string connectionId = "Random")
|
||||
{
|
||||
IDictionary<string, object> env = new Dictionary<string, object>();
|
||||
var requestHeaders = new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase);
|
||||
env["owin.RequestHeaders"] = requestHeaders;
|
||||
if (header != null)
|
||||
{
|
||||
requestHeaders[header] = new string[] { value };
|
||||
}
|
||||
env["owin.ResponseHeaders"] = new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
var onSendingHeadersActions = new List<Tuple<Action<object>, object>>();
|
||||
env["server.OnSendingHeaders"] = new Action<Action<object>, object>(
|
||||
(a, b) => onSendingHeadersActions.Add(new Tuple<Action<object>, object>(a, b)));
|
||||
|
||||
env["test.OnSendingHeadersActions"] = onSendingHeadersActions;
|
||||
env["server.ConnectionId"] = connectionId;
|
||||
return env;
|
||||
}
|
||||
|
||||
private void FireOnSendingHeadersActions(IDictionary<string, object> env)
|
||||
{
|
||||
var onSendingHeadersActions = env.Get<IList<Tuple<Action<object>, object>>>("test.OnSendingHeadersActions");
|
||||
foreach (var actionPair in onSendingHeadersActions.Reverse())
|
||||
{
|
||||
actionPair.Item1(actionPair.Item2);
|
||||
}
|
||||
}
|
||||
|
||||
private IDisposable CreateServer(AppFunc app)
|
||||
{
|
||||
IDictionary<string, object> properties = new Dictionary<string, object>();
|
||||
IList<IDictionary<string, object>> addresses = new List<IDictionary<string, object>>();
|
||||
properties["host.Addresses"] = addresses;
|
||||
|
||||
IDictionary<string, object> address = new Dictionary<string, object>();
|
||||
addresses.Add(address);
|
||||
|
||||
address["scheme"] = "http";
|
||||
address["host"] = "localhost";
|
||||
address["port"] = "8080";
|
||||
address["path"] = string.Empty;
|
||||
|
||||
return OwinServerFactory.Create(app, properties);
|
||||
}
|
||||
|
||||
private IDisposable CreateSecureServer(AppFunc app)
|
||||
{
|
||||
IDictionary<string, object> properties = new Dictionary<string, object>();
|
||||
IList<IDictionary<string, object>> addresses = new List<IDictionary<string, object>>();
|
||||
properties["host.Addresses"] = addresses;
|
||||
|
||||
IDictionary<string, object> address = new Dictionary<string, object>();
|
||||
addresses.Add(address);
|
||||
|
||||
address["scheme"] = "https";
|
||||
address["host"] = "localhost";
|
||||
address["port"] = "9090";
|
||||
address["path"] = string.Empty;
|
||||
|
||||
return OwinServerFactory.Create(app, properties);
|
||||
}
|
||||
|
||||
private async Task<HttpResponseMessage> SendRequestAsync(string uri)
|
||||
{
|
||||
using (HttpClient client = new HttpClient())
|
||||
{
|
||||
return await client.GetAsync(uri);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<HttpResponseMessage> SendAuthRequestAsync(string uri)
|
||||
{
|
||||
WebRequestHandler handler = new WebRequestHandler();
|
||||
handler.UseDefaultCredentials = true;
|
||||
handler.ServerCertificateValidationCallback = (a, b, c, d) => true;
|
||||
using (HttpClient client = new HttpClient(handler))
|
||||
{
|
||||
return await client.GetAsync(uri);
|
||||
}
|
||||
}
|
||||
|
||||
private Task SimpleApp(IDictionary<string, object> env)
|
||||
{
|
||||
env["owin.ResponseStatusCode"] = DefaultStatusCode;
|
||||
return Task.FromResult<object>(null);
|
||||
}
|
||||
|
||||
private Task SimpleApp401(IDictionary<string, object> env)
|
||||
{
|
||||
env["owin.ResponseStatusCode"] = 401;
|
||||
return Task.FromResult<object>(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,81 +0,0 @@
|
|||
// 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="PassThroughTests.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows.Tests
|
||||
{
|
||||
public class PassThroughTests
|
||||
{
|
||||
private const int DefaultStatusCode = 201;
|
||||
|
||||
[Fact]
|
||||
public async Task PassThrough_EmptyRequest_Success()
|
||||
{
|
||||
WindowsAuthMiddleware windowsAuth = new WindowsAuthMiddleware(SimpleApp);
|
||||
IDictionary<string, object> emptyEnv = CreateEmptyRequest();
|
||||
await windowsAuth.Invoke(emptyEnv);
|
||||
|
||||
Assert.Equal(DefaultStatusCode, emptyEnv.Get<int>("owin.ResponseStatusCode"));
|
||||
var responseHeaders = emptyEnv.Get<IDictionary<string, string[]>>("owin.ResponseHeaders");
|
||||
Assert.Equal(0, responseHeaders.Count);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task PassThrough_BasicAuth_Success()
|
||||
{
|
||||
WindowsAuthMiddleware windowsAuth = new WindowsAuthMiddleware(SimpleApp);
|
||||
IDictionary<string, object> emptyEnv = CreateEmptyRequest("Authorization", "Basic blablabla");
|
||||
await windowsAuth.Invoke(emptyEnv);
|
||||
|
||||
Assert.Equal(DefaultStatusCode, emptyEnv.Get<int>("owin.ResponseStatusCode"));
|
||||
var responseHeaders = emptyEnv.Get<IDictionary<string, string[]>>("owin.ResponseHeaders");
|
||||
Assert.Equal(0, responseHeaders.Count);
|
||||
}
|
||||
|
||||
private IDictionary<string, object> CreateEmptyRequest(string header = null, string value = null)
|
||||
{
|
||||
IDictionary<string, object> env = new Dictionary<string, object>();
|
||||
var requestHeaders = new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase);
|
||||
env["owin.RequestHeaders"] = requestHeaders;
|
||||
if (header != null)
|
||||
{
|
||||
requestHeaders[header] = new string[] { value };
|
||||
}
|
||||
env["owin.ResponseHeaders"] = new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase);
|
||||
env["server.OnSendingHeaders"] = new Action<Action<object>, object>((a, b) => { });
|
||||
return env;
|
||||
}
|
||||
|
||||
private Task SimpleApp(IDictionary<string, object> env)
|
||||
{
|
||||
env["owin.ResponseStatusCode"] = DefaultStatusCode;
|
||||
return Task.FromResult<object>(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
// 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="AssemblyInfo.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("Microsoft.AspNet.Security.Windows.Tests")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Microsoft.AspNet.Security.Windows.Tests")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2012")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("334c99b0-a718-4cda-9ca0-d5a45c3a32b0")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("0.5")]
|
||||
[assembly: AssemblyVersion("0.5")]
|
||||
[assembly: AssemblyFileVersion("0.5.40117.0")]
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"Microsoft.AspNet.Security.Windows" : "",
|
||||
"Microsoft.AspNet.Server.WebListener" : "",
|
||||
"xunit.abstractions": "2.0.0-aspnet-*",
|
||||
"xunit.assert": "2.0.0-aspnet-*",
|
||||
"xunit.core": "2.0.0-aspnet-*",
|
||||
"xunit.execution": "2.0.0-aspnet-*"
|
||||
},
|
||||
"frameworks": {
|
||||
"aspnet50": {
|
||||
"dependencies": {
|
||||
"System.Net.Http": "",
|
||||
"System.Net.Http.WebRequest": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue