Switch to new host apis (#23783)

* Update tests

* Switch to new host apis

* Update host apis

* Update CookieTests.cs

* Update tests

* PR feedback/cleanup

* More cleanup
This commit is contained in:
Hao Kung 2020-07-10 17:56:18 -07:00 committed by GitHub
parent 241e45d2b9
commit fae3dd12ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 1482 additions and 1151 deletions

View File

@ -18,6 +18,7 @@ using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity.Test; using Microsoft.AspNetCore.Identity.Test;
using Microsoft.AspNetCore.TestHost; using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Net.Http.Headers; using Microsoft.Net.Http.Headers;
using Xunit; using Xunit;
@ -31,7 +32,7 @@ namespace Microsoft.AspNetCore.Identity.InMemory
public async Task CanChangePasswordOptions() public async Task CanChangePasswordOptions()
{ {
var clock = new TestClock(); var clock = new TestClock();
var server = CreateServer(services => services.Configure<IdentityOptions>(options => var server = await CreateServer(services => services.Configure<IdentityOptions>(options =>
{ {
options.Password.RequireUppercase = false; options.Password.RequireUppercase = false;
options.Password.RequireNonAlphanumeric = false; options.Password.RequireNonAlphanumeric = false;
@ -49,7 +50,7 @@ namespace Microsoft.AspNetCore.Identity.InMemory
public async Task CookieContainsRoleClaim() public async Task CookieContainsRoleClaim()
{ {
var clock = new TestClock(); var clock = new TestClock();
var server = CreateServer(null, null, null, testCore: true); var server = await CreateServer(null, null, null, testCore: true);
var transaction1 = await SendAsync(server, "http://example.com/createMe"); var transaction1 = await SendAsync(server, "http://example.com/createMe");
Assert.Equal(HttpStatusCode.OK, transaction1.Response.StatusCode); Assert.Equal(HttpStatusCode.OK, transaction1.Response.StatusCode);
@ -70,7 +71,7 @@ namespace Microsoft.AspNetCore.Identity.InMemory
public async Task CanCreateMeLoginAndCookieStopsWorkingAfterExpiration() public async Task CanCreateMeLoginAndCookieStopsWorkingAfterExpiration()
{ {
var clock = new TestClock(); var clock = new TestClock();
var server = CreateServer(services => var server = await CreateServer(services =>
{ {
services.ConfigureApplicationCookie(options => services.ConfigureApplicationCookie(options =>
{ {
@ -112,7 +113,7 @@ namespace Microsoft.AspNetCore.Identity.InMemory
public async Task CanCreateMeLoginAndSecurityStampExtendsExpiration(bool rememberMe) public async Task CanCreateMeLoginAndSecurityStampExtendsExpiration(bool rememberMe)
{ {
var clock = new TestClock(); var clock = new TestClock();
var server = CreateServer(services => services.AddSingleton<ISystemClock>(clock)); var server = await CreateServer(services => services.AddSingleton<ISystemClock>(clock));
var transaction1 = await SendAsync(server, "http://example.com/createMe"); var transaction1 = await SendAsync(server, "http://example.com/createMe");
Assert.Equal(HttpStatusCode.OK, transaction1.Response.StatusCode); Assert.Equal(HttpStatusCode.OK, transaction1.Response.StatusCode);
@ -156,7 +157,7 @@ namespace Microsoft.AspNetCore.Identity.InMemory
public async Task CanAccessOldPrincipalDuringSecurityStampReplacement() public async Task CanAccessOldPrincipalDuringSecurityStampReplacement()
{ {
var clock = new TestClock(); var clock = new TestClock();
var server = CreateServer(services => var server = await CreateServer(services =>
{ {
services.Configure<SecurityStampValidatorOptions>(options => services.Configure<SecurityStampValidatorOptions>(options =>
{ {
@ -207,7 +208,7 @@ namespace Microsoft.AspNetCore.Identity.InMemory
public async Task TwoFactorRememberCookieVerification() public async Task TwoFactorRememberCookieVerification()
{ {
var clock = new TestClock(); var clock = new TestClock();
var server = CreateServer(services => services.AddSingleton<ISystemClock>(clock)); var server = await CreateServer(services => services.AddSingleton<ISystemClock>(clock));
var transaction1 = await SendAsync(server, "http://example.com/createMe"); var transaction1 = await SendAsync(server, "http://example.com/createMe");
Assert.Equal(HttpStatusCode.OK, transaction1.Response.StatusCode); Assert.Equal(HttpStatusCode.OK, transaction1.Response.StatusCode);
@ -234,7 +235,7 @@ namespace Microsoft.AspNetCore.Identity.InMemory
public async Task TwoFactorRememberCookieClearedBySecurityStampChange() public async Task TwoFactorRememberCookieClearedBySecurityStampChange()
{ {
var clock = new TestClock(); var clock = new TestClock();
var server = CreateServer(services => services.AddSingleton<ISystemClock>(clock)); var server = await CreateServer(services => services.AddSingleton<ISystemClock>(clock));
var transaction1 = await SendAsync(server, "http://example.com/createMe"); var transaction1 = await SendAsync(server, "http://example.com/createMe");
Assert.Equal(HttpStatusCode.OK, transaction1.Response.StatusCode); Assert.Equal(HttpStatusCode.OK, transaction1.Response.StatusCode);
@ -285,10 +286,11 @@ namespace Microsoft.AspNetCore.Identity.InMemory
return me; return me;
} }
private static TestServer CreateServer(Action<IServiceCollection> configureServices = null, Func<HttpContext, Task> testpath = null, Uri baseAddress = null, bool testCore = false) private static async Task<TestServer> CreateServer(Action<IServiceCollection> configureServices = null, Func<HttpContext, Task> testpath = null, Uri baseAddress = null, bool testCore = false)
{ {
var builder = new WebHostBuilder() var host = new HostBuilder()
.Configure(app => .ConfigureWebHost(builder =>
builder.Configure(app =>
{ {
app.UseAuthentication(); app.UseAuthentication();
app.Use(async (context, next) => app.Use(async (context, next) =>
@ -388,8 +390,11 @@ namespace Microsoft.AspNetCore.Identity.InMemory
services.AddSingleton<IUserStore<PocoUser>>(store); services.AddSingleton<IUserStore<PocoUser>>(store);
services.AddSingleton<IRoleStore<PocoRole>>(store); services.AddSingleton<IRoleStore<PocoRole>>(store);
configureServices?.Invoke(services); configureServices?.Invoke(services);
}); })
var server = new TestServer(builder); .UseTestServer())
.Build();
await host.StartAsync();
var server = host.GetTestServer();
server.BaseAddress = baseAddress; server.BaseAddress = baseAddress;
return server; return server;
} }

View File

@ -8,6 +8,7 @@ using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.TestHost; using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Xunit; using Xunit;
namespace Microsoft.AspNetCore.Authentication namespace Microsoft.AspNetCore.Authentication
@ -17,7 +18,9 @@ namespace Microsoft.AspNetCore.Authentication
[Fact] [Fact]
public async Task OnlyInvokesCanHandleRequestHandlers() public async Task OnlyInvokesCanHandleRequestHandlers()
{ {
var builder = new WebHostBuilder() using var host = new HostBuilder()
.ConfigureWebHost(builder =>
builder.UseTestServer()
.Configure(app => .Configure(app =>
{ {
app.UseAuthentication(); app.UseAuthentication();
@ -42,8 +45,11 @@ namespace Microsoft.AspNetCore.Authentication
{ {
s.HandlerType = typeof(ThreeOhFiveHandler); s.HandlerType = typeof(ThreeOhFiveHandler);
}); });
})); })))
var server = new TestServer(builder); .Build();
await host.StartAsync();
using var server = host.GetTestServer();
var response = await server.CreateClient().GetAsync("http://example.com/"); var response = await server.CreateClient().GetAsync("http://example.com/");
Assert.Equal(607, (int)response.StatusCode); Assert.Equal(607, (int)response.StatusCode);
} }
@ -191,6 +197,5 @@ namespace Microsoft.AspNetCore.Authentication
throw new NotImplementedException(); throw new NotImplementedException();
} }
} }
} }
} }

View File

@ -15,6 +15,7 @@ using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.TestHost; using Microsoft.AspNetCore.TestHost;
using Microsoft.AspNetCore.Testing; using Microsoft.AspNetCore.Testing;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Xunit; using Xunit;
namespace Microsoft.AspNetCore.Authentication.Certificate.Test namespace Microsoft.AspNetCore.Authentication.Certificate.Test
@ -44,7 +45,7 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
[Fact] [Fact]
public async Task VerifyValidSelfSignedWithClientEkuAuthenticates() public async Task VerifyValidSelfSignedWithClientEkuAuthenticates()
{ {
var server = CreateServer( using var host = await CreateHost(
new CertificateAuthenticationOptions new CertificateAuthenticationOptions
{ {
AllowedCertificateTypes = CertificateTypes.SelfSigned, AllowedCertificateTypes = CertificateTypes.SelfSigned,
@ -52,6 +53,7 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
}, },
Certificates.SelfSignedValidWithClientEku); Certificates.SelfSignedValidWithClientEku);
using var server = host.GetTestServer();
var response = await server.CreateClient().GetAsync("https://example.com/"); var response = await server.CreateClient().GetAsync("https://example.com/");
Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(HttpStatusCode.OK, response.StatusCode);
} }
@ -59,7 +61,7 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
[Fact] [Fact]
public async Task VerifyValidSelfSignedWithNoEkuAuthenticates() public async Task VerifyValidSelfSignedWithNoEkuAuthenticates()
{ {
var server = CreateServer( using var host = await CreateHost(
new CertificateAuthenticationOptions new CertificateAuthenticationOptions
{ {
AllowedCertificateTypes = CertificateTypes.SelfSigned, AllowedCertificateTypes = CertificateTypes.SelfSigned,
@ -67,6 +69,7 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
}, },
Certificates.SelfSignedValidWithNoEku); Certificates.SelfSignedValidWithNoEku);
using var server = host.GetTestServer();
var response = await server.CreateClient().GetAsync("https://example.com/"); var response = await server.CreateClient().GetAsync("https://example.com/");
Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(HttpStatusCode.OK, response.StatusCode);
} }
@ -74,13 +77,14 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
[Fact] [Fact]
public async Task VerifyValidSelfSignedWithClientEkuFailsWhenSelfSignedCertsNotAllowed() public async Task VerifyValidSelfSignedWithClientEkuFailsWhenSelfSignedCertsNotAllowed()
{ {
var server = CreateServer( using var host = await CreateHost(
new CertificateAuthenticationOptions new CertificateAuthenticationOptions
{ {
AllowedCertificateTypes = CertificateTypes.Chained AllowedCertificateTypes = CertificateTypes.Chained
}, },
Certificates.SelfSignedValidWithClientEku); Certificates.SelfSignedValidWithClientEku);
using var server = host.GetTestServer();
var response = await server.CreateClient().GetAsync("https://example.com/"); var response = await server.CreateClient().GetAsync("https://example.com/");
Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode); Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode);
} }
@ -88,7 +92,7 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
[Fact] [Fact]
public async Task VerifyValidSelfSignedWithNoEkuFailsWhenSelfSignedCertsNotAllowed() public async Task VerifyValidSelfSignedWithNoEkuFailsWhenSelfSignedCertsNotAllowed()
{ {
var server = CreateServer( using var host = await CreateHost(
new CertificateAuthenticationOptions new CertificateAuthenticationOptions
{ {
AllowedCertificateTypes = CertificateTypes.Chained, AllowedCertificateTypes = CertificateTypes.Chained,
@ -96,6 +100,7 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
}, },
Certificates.SelfSignedValidWithNoEku); Certificates.SelfSignedValidWithNoEku);
using var server = host.GetTestServer();
var response = await server.CreateClient().GetAsync("https://example.com/"); var response = await server.CreateClient().GetAsync("https://example.com/");
Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode); Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode);
} }
@ -103,7 +108,7 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
[Fact] [Fact]
public async Task VerifyValidSelfSignedWithServerFailsEvenIfSelfSignedCertsAreAllowed() public async Task VerifyValidSelfSignedWithServerFailsEvenIfSelfSignedCertsAreAllowed()
{ {
var server = CreateServer( using var host = await CreateHost(
new CertificateAuthenticationOptions new CertificateAuthenticationOptions
{ {
AllowedCertificateTypes = CertificateTypes.SelfSigned, AllowedCertificateTypes = CertificateTypes.SelfSigned,
@ -111,6 +116,7 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
}, },
Certificates.SelfSignedValidWithServerEku); Certificates.SelfSignedValidWithServerEku);
using var server = host.GetTestServer();
var response = await server.CreateClient().GetAsync("https://example.com/"); var response = await server.CreateClient().GetAsync("https://example.com/");
Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode); Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode);
} }
@ -118,7 +124,7 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
[Fact] [Fact]
public async Task VerifyValidSelfSignedWithServerPassesWhenSelfSignedCertsAreAllowedAndPurposeValidationIsOff() public async Task VerifyValidSelfSignedWithServerPassesWhenSelfSignedCertsAreAllowedAndPurposeValidationIsOff()
{ {
var server = CreateServer( using var host = await CreateHost(
new CertificateAuthenticationOptions new CertificateAuthenticationOptions
{ {
AllowedCertificateTypes = CertificateTypes.SelfSigned, AllowedCertificateTypes = CertificateTypes.SelfSigned,
@ -127,6 +133,7 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
}, },
Certificates.SelfSignedValidWithServerEku); Certificates.SelfSignedValidWithServerEku);
using var server = host.GetTestServer();
var response = await server.CreateClient().GetAsync("https://example.com/"); var response = await server.CreateClient().GetAsync("https://example.com/");
Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(HttpStatusCode.OK, response.StatusCode);
} }
@ -134,7 +141,7 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
[Fact] [Fact]
public async Task VerifyValidSelfSignedWithServerFailsPurposeValidationIsOffButSelfSignedCertsAreNotAllowed() public async Task VerifyValidSelfSignedWithServerFailsPurposeValidationIsOffButSelfSignedCertsAreNotAllowed()
{ {
var server = CreateServer( using var host = await CreateHost(
new CertificateAuthenticationOptions new CertificateAuthenticationOptions
{ {
AllowedCertificateTypes = CertificateTypes.Chained, AllowedCertificateTypes = CertificateTypes.Chained,
@ -143,6 +150,7 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
}, },
Certificates.SelfSignedValidWithServerEku); Certificates.SelfSignedValidWithServerEku);
using var server = host.GetTestServer();
var response = await server.CreateClient().GetAsync("https://example.com/"); var response = await server.CreateClient().GetAsync("https://example.com/");
Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode); Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode);
} }
@ -150,7 +158,7 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
[Fact] [Fact]
public async Task VerifyExpiredSelfSignedFails() public async Task VerifyExpiredSelfSignedFails()
{ {
var server = CreateServer( using var host = await CreateHost(
new CertificateAuthenticationOptions new CertificateAuthenticationOptions
{ {
AllowedCertificateTypes = CertificateTypes.SelfSigned, AllowedCertificateTypes = CertificateTypes.SelfSigned,
@ -159,6 +167,7 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
}, },
Certificates.SelfSignedExpired); Certificates.SelfSignedExpired);
using var server = host.GetTestServer();
var response = await server.CreateClient().GetAsync("https://example.com/"); var response = await server.CreateClient().GetAsync("https://example.com/");
Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode); Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode);
} }
@ -166,7 +175,7 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
[Fact] [Fact]
public async Task VerifyExpiredSelfSignedPassesIfDateRangeValidationIsDisabled() public async Task VerifyExpiredSelfSignedPassesIfDateRangeValidationIsDisabled()
{ {
var server = CreateServer( using var host = await CreateHost(
new CertificateAuthenticationOptions new CertificateAuthenticationOptions
{ {
AllowedCertificateTypes = CertificateTypes.SelfSigned, AllowedCertificateTypes = CertificateTypes.SelfSigned,
@ -175,6 +184,7 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
}, },
Certificates.SelfSignedExpired); Certificates.SelfSignedExpired);
using var server = host.GetTestServer();
var response = await server.CreateClient().GetAsync("https://example.com/"); var response = await server.CreateClient().GetAsync("https://example.com/");
Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(HttpStatusCode.OK, response.StatusCode);
} }
@ -182,7 +192,7 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
[Fact] [Fact]
public async Task VerifyNotYetValidSelfSignedFails() public async Task VerifyNotYetValidSelfSignedFails()
{ {
var server = CreateServer( using var host = await CreateHost(
new CertificateAuthenticationOptions new CertificateAuthenticationOptions
{ {
AllowedCertificateTypes = CertificateTypes.SelfSigned, AllowedCertificateTypes = CertificateTypes.SelfSigned,
@ -191,6 +201,7 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
}, },
Certificates.SelfSignedNotYetValid); Certificates.SelfSignedNotYetValid);
using var server = host.GetTestServer();
var response = await server.CreateClient().GetAsync("https://example.com/"); var response = await server.CreateClient().GetAsync("https://example.com/");
Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode); Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode);
} }
@ -198,7 +209,7 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
[Fact] [Fact]
public async Task VerifyNotYetValidSelfSignedPassesIfDateRangeValidationIsDisabled() public async Task VerifyNotYetValidSelfSignedPassesIfDateRangeValidationIsDisabled()
{ {
var server = CreateServer( using var host = await CreateHost(
new CertificateAuthenticationOptions new CertificateAuthenticationOptions
{ {
AllowedCertificateTypes = CertificateTypes.SelfSigned, AllowedCertificateTypes = CertificateTypes.SelfSigned,
@ -207,6 +218,7 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
}, },
Certificates.SelfSignedNotYetValid); Certificates.SelfSignedNotYetValid);
using var server = host.GetTestServer();
var response = await server.CreateClient().GetAsync("https://example.com/"); var response = await server.CreateClient().GetAsync("https://example.com/");
Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(HttpStatusCode.OK, response.StatusCode);
} }
@ -214,7 +226,7 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
[Fact] [Fact]
public async Task VerifyFailingInTheValidationEventReturnsForbidden() public async Task VerifyFailingInTheValidationEventReturnsForbidden()
{ {
var server = CreateServer( using var host = await CreateHost(
new CertificateAuthenticationOptions new CertificateAuthenticationOptions
{ {
ValidateCertificateUse = false, ValidateCertificateUse = false,
@ -222,6 +234,7 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
}, },
Certificates.SelfSignedValidWithServerEku); Certificates.SelfSignedValidWithServerEku);
using var server = host.GetTestServer();
var response = await server.CreateClient().GetAsync("https://example.com/"); var response = await server.CreateClient().GetAsync("https://example.com/");
Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode); Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode);
} }
@ -229,7 +242,7 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
[Fact] [Fact]
public async Task DoingNothingInTheValidationEventReturnsOK() public async Task DoingNothingInTheValidationEventReturnsOK()
{ {
var server = CreateServer( using var host = await CreateHost(
new CertificateAuthenticationOptions new CertificateAuthenticationOptions
{ {
AllowedCertificateTypes = CertificateTypes.SelfSigned, AllowedCertificateTypes = CertificateTypes.SelfSigned,
@ -238,6 +251,7 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
}, },
Certificates.SelfSignedValidWithServerEku); Certificates.SelfSignedValidWithServerEku);
using var server = host.GetTestServer();
var response = await server.CreateClient().GetAsync("https://example.com/"); var response = await server.CreateClient().GetAsync("https://example.com/");
Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(HttpStatusCode.OK, response.StatusCode);
} }
@ -245,12 +259,13 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
[Fact] [Fact]
public async Task VerifyNotSendingACertificateEndsUpInForbidden() public async Task VerifyNotSendingACertificateEndsUpInForbidden()
{ {
var server = CreateServer( using var host = await CreateHost(
new CertificateAuthenticationOptions new CertificateAuthenticationOptions
{ {
Events = successfulValidationEvents Events = successfulValidationEvents
}); });
using var server = host.GetTestServer();
var response = await server.CreateClient().GetAsync("https://example.com/"); var response = await server.CreateClient().GetAsync("https://example.com/");
Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode); Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode);
} }
@ -258,12 +273,13 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
[Fact] [Fact]
public async Task VerifyUntrustedClientCertEndsUpInForbidden() public async Task VerifyUntrustedClientCertEndsUpInForbidden()
{ {
var server = CreateServer( using var host = await CreateHost(
new CertificateAuthenticationOptions new CertificateAuthenticationOptions
{ {
Events = successfulValidationEvents Events = successfulValidationEvents
}, Certificates.SignedClient); }, Certificates.SignedClient);
using var server = host.GetTestServer();
var response = await server.CreateClient().GetAsync("https://example.com/"); var response = await server.CreateClient().GetAsync("https://example.com/");
Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode); Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode);
} }
@ -271,7 +287,7 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
[Fact] [Fact]
public async Task VerifyClientCertWithUntrustedRootAndTrustedChainEndsUpInForbidden() public async Task VerifyClientCertWithUntrustedRootAndTrustedChainEndsUpInForbidden()
{ {
var server = CreateServer( using var host = await CreateHost(
new CertificateAuthenticationOptions new CertificateAuthenticationOptions
{ {
Events = successfulValidationEvents, Events = successfulValidationEvents,
@ -280,6 +296,7 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
RevocationMode = X509RevocationMode.NoCheck RevocationMode = X509RevocationMode.NoCheck
}, Certificates.SignedClient); }, Certificates.SignedClient);
using var server = host.GetTestServer();
var response = await server.CreateClient().GetAsync("https://example.com/"); var response = await server.CreateClient().GetAsync("https://example.com/");
Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode); Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode);
} }
@ -287,7 +304,7 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
[Fact] [Fact]
public async Task VerifyValidClientCertWithTrustedChainAuthenticates() public async Task VerifyValidClientCertWithTrustedChainAuthenticates()
{ {
var server = CreateServer( using var host = await CreateHost(
new CertificateAuthenticationOptions new CertificateAuthenticationOptions
{ {
Events = successfulValidationEvents, Events = successfulValidationEvents,
@ -296,6 +313,7 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
RevocationMode = X509RevocationMode.NoCheck RevocationMode = X509RevocationMode.NoCheck
}, Certificates.SignedClient); }, Certificates.SignedClient);
using var server = host.GetTestServer();
var response = await server.CreateClient().GetAsync("https://example.com/"); var response = await server.CreateClient().GetAsync("https://example.com/");
Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(HttpStatusCode.OK, response.StatusCode);
} }
@ -303,7 +321,7 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
[Fact] [Fact]
public async Task VerifyHeaderIsUsedIfCertIsNotPresent() public async Task VerifyHeaderIsUsedIfCertIsNotPresent()
{ {
var server = CreateServer( using var host = await CreateHost(
new CertificateAuthenticationOptions new CertificateAuthenticationOptions
{ {
AllowedCertificateTypes = CertificateTypes.SelfSigned, AllowedCertificateTypes = CertificateTypes.SelfSigned,
@ -311,6 +329,7 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
}, },
wireUpHeaderMiddleware: true); wireUpHeaderMiddleware: true);
using var server = host.GetTestServer();
var client = server.CreateClient(); var client = server.CreateClient();
client.DefaultRequestHeaders.Add("X-Client-Cert", Convert.ToBase64String(Certificates.SelfSignedValidWithNoEku.RawData)); client.DefaultRequestHeaders.Add("X-Client-Cert", Convert.ToBase64String(Certificates.SelfSignedValidWithNoEku.RawData));
var response = await client.GetAsync("https://example.com/"); var response = await client.GetAsync("https://example.com/");
@ -320,13 +339,14 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
[Fact] [Fact]
public async Task VerifyHeaderEncodedCertFailsOnBadEncoding() public async Task VerifyHeaderEncodedCertFailsOnBadEncoding()
{ {
var server = CreateServer( using var host = await CreateHost(
new CertificateAuthenticationOptions new CertificateAuthenticationOptions
{ {
Events = successfulValidationEvents Events = successfulValidationEvents
}, },
wireUpHeaderMiddleware: true); wireUpHeaderMiddleware: true);
using var server = host.GetTestServer();
var client = server.CreateClient(); var client = server.CreateClient();
client.DefaultRequestHeaders.Add("X-Client-Cert", "OOPS" + Convert.ToBase64String(Certificates.SelfSignedValidWithNoEku.RawData)); client.DefaultRequestHeaders.Add("X-Client-Cert", "OOPS" + Convert.ToBase64String(Certificates.SelfSignedValidWithNoEku.RawData));
var response = await client.GetAsync("https://example.com/"); var response = await client.GetAsync("https://example.com/");
@ -336,7 +356,7 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
[Fact] [Fact]
public async Task VerifySettingTheAzureHeaderOnTheForwarderOptionsWorks() public async Task VerifySettingTheAzureHeaderOnTheForwarderOptionsWorks()
{ {
var server = CreateServer( using var host = await CreateHost(
new CertificateAuthenticationOptions new CertificateAuthenticationOptions
{ {
AllowedCertificateTypes = CertificateTypes.SelfSigned, AllowedCertificateTypes = CertificateTypes.SelfSigned,
@ -345,6 +365,7 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
wireUpHeaderMiddleware: true, wireUpHeaderMiddleware: true,
headerName: "X-ARR-ClientCert"); headerName: "X-ARR-ClientCert");
using var server = host.GetTestServer();
var client = server.CreateClient(); var client = server.CreateClient();
client.DefaultRequestHeaders.Add("X-ARR-ClientCert", Convert.ToBase64String(Certificates.SelfSignedValidWithNoEku.RawData)); client.DefaultRequestHeaders.Add("X-ARR-ClientCert", Convert.ToBase64String(Certificates.SelfSignedValidWithNoEku.RawData));
var response = await client.GetAsync("https://example.com/"); var response = await client.GetAsync("https://example.com/");
@ -354,7 +375,7 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
[Fact] [Fact]
public async Task VerifyACustomHeaderFailsIfTheHeaderIsNotPresent() public async Task VerifyACustomHeaderFailsIfTheHeaderIsNotPresent()
{ {
var server = CreateServer( using var host = await CreateHost(
new CertificateAuthenticationOptions new CertificateAuthenticationOptions
{ {
Events = successfulValidationEvents Events = successfulValidationEvents
@ -362,6 +383,7 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
wireUpHeaderMiddleware: true, wireUpHeaderMiddleware: true,
headerName: "X-ARR-ClientCert"); headerName: "X-ARR-ClientCert");
using var server = host.GetTestServer();
var client = server.CreateClient(); var client = server.CreateClient();
client.DefaultRequestHeaders.Add("random-Weird-header", Convert.ToBase64String(Certificates.SelfSignedValidWithNoEku.RawData)); client.DefaultRequestHeaders.Add("random-Weird-header", Convert.ToBase64String(Certificates.SelfSignedValidWithNoEku.RawData));
var response = await client.GetAsync("https://example.com/"); var response = await client.GetAsync("https://example.com/");
@ -371,13 +393,14 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
[Fact] [Fact]
public async Task VerifyNoEventWireupWithAValidCertificateCreatesADefaultUser() public async Task VerifyNoEventWireupWithAValidCertificateCreatesADefaultUser()
{ {
var server = CreateServer( using var host = await CreateHost(
new CertificateAuthenticationOptions new CertificateAuthenticationOptions
{ {
AllowedCertificateTypes = CertificateTypes.SelfSigned AllowedCertificateTypes = CertificateTypes.SelfSigned
}, },
Certificates.SelfSignedValidWithNoEku); Certificates.SelfSignedValidWithNoEku);
using var server = host.GetTestServer();
var response = await server.CreateClient().GetAsync("https://example.com/"); var response = await server.CreateClient().GetAsync("https://example.com/");
Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(HttpStatusCode.OK, response.StatusCode);
@ -481,7 +504,7 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
const string Expected = "John Doe"; const string Expected = "John Doe";
var validationCount = 0; var validationCount = 0;
var server = CreateServer( using var host = await CreateHost(
new CertificateAuthenticationOptions new CertificateAuthenticationOptions
{ {
AllowedCertificateTypes = CertificateTypes.SelfSigned, AllowedCertificateTypes = CertificateTypes.SelfSigned,
@ -508,6 +531,7 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
}, },
Certificates.SelfSignedValidWithNoEku, null, null, false, "", cache); Certificates.SelfSignedValidWithNoEku, null, null, false, "", cache);
using var server = host.GetTestServer();
var response = await server.CreateClient().GetAsync("https://example.com/"); var response = await server.CreateClient().GetAsync("https://example.com/");
Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(HttpStatusCode.OK, response.StatusCode);
@ -554,7 +578,7 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
{ {
const string Expected = "John Doe"; const string Expected = "John Doe";
var server = CreateServer( using var host = await CreateHost(
new CertificateAuthenticationOptions new CertificateAuthenticationOptions
{ {
AllowedCertificateTypes = CertificateTypes.SelfSigned, AllowedCertificateTypes = CertificateTypes.SelfSigned,
@ -577,6 +601,7 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
}, },
Certificates.SelfSignedValidWithNoEku); Certificates.SelfSignedValidWithNoEku);
using var server = host.GetTestServer();
var response = await server.CreateClient().GetAsync("https://example.com/"); var response = await server.CreateClient().GetAsync("https://example.com/");
Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(HttpStatusCode.OK, response.StatusCode);
@ -596,7 +621,7 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
Assert.Single(responseAsXml.Elements("claim")); Assert.Single(responseAsXml.Elements("claim"));
} }
private static TestServer CreateServer( private static async Task<IHost> CreateHost(
CertificateAuthenticationOptions configureOptions, CertificateAuthenticationOptions configureOptions,
X509Certificate2 clientCertificate = null, X509Certificate2 clientCertificate = null,
Func<HttpContext, bool> handler = null, Func<HttpContext, bool> handler = null,
@ -605,7 +630,9 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
string headerName = "", string headerName = "",
bool useCache = false) bool useCache = false)
{ {
var builder = new WebHostBuilder() var host = new HostBuilder()
.ConfigureWebHost(builder =>
builder.UseTestServer()
.Configure(app => .Configure(app =>
{ {
app.Use((context, next) => app.Use((context, next) =>
@ -683,14 +710,15 @@ namespace Microsoft.AspNetCore.Authentication.Certificate.Test
options.CertificateHeader = headerName; options.CertificateHeader = headerName;
}); });
} }
}); }))
.Build();
var server = new TestServer(builder) await host.StartAsync();
{
BaseAddress = baseAddress
};
return server;
var server = host.GetTestServer();
server.BaseAddress = baseAddress;
return host;
} }
private CertificateAuthenticationEvents successfulValidationEvents = new CertificateAuthenticationEvents() private CertificateAuthenticationEvents successfulValidationEvents = new CertificateAuthenticationEvents()

View File

@ -17,6 +17,7 @@ using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.TestHost; using Microsoft.AspNetCore.TestHost;
using Microsoft.AspNetCore.Testing; using Microsoft.AspNetCore.Testing;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Xunit; using Xunit;
@ -37,7 +38,8 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
[Fact] [Fact]
public async Task NormalRequestPassesThrough() public async Task NormalRequestPassesThrough()
{ {
var server = CreateServer(s => { }); using var host = await CreateHost(s => { });
using var server = host.GetTestServer();
var response = await server.CreateClient().GetAsync("http://example.com/normal"); var response = await server.CreateClient().GetAsync("http://example.com/normal");
Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(HttpStatusCode.OK, response.StatusCode);
} }
@ -45,7 +47,8 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
[Fact] [Fact]
public async Task AjaxLoginRedirectToReturnUrlTurnsInto200WithLocationHeader() public async Task AjaxLoginRedirectToReturnUrlTurnsInto200WithLocationHeader()
{ {
var server = CreateServer(o => o.LoginPath = "/login"); using var host = await CreateHost(o => o.LoginPath = "/login");
using var server = host.GetTestServer();
var transaction = await SendAsync(server, "http://example.com/challenge?X-Requested-With=XMLHttpRequest"); var transaction = await SendAsync(server, "http://example.com/challenge?X-Requested-With=XMLHttpRequest");
Assert.Equal(HttpStatusCode.Unauthorized, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.Unauthorized, transaction.Response.StatusCode);
var responded = transaction.Response.Headers.GetValues("Location"); var responded = transaction.Response.Headers.GetValues("Location");
@ -56,7 +59,8 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
[Fact] [Fact]
public async Task AjaxForbidTurnsInto403WithLocationHeader() public async Task AjaxForbidTurnsInto403WithLocationHeader()
{ {
var server = CreateServer(o => o.AccessDeniedPath = "/denied"); using var host = await CreateHost(o => o.AccessDeniedPath = "/denied");
using var server = host.GetTestServer();
var transaction = await SendAsync(server, "http://example.com/forbid?X-Requested-With=XMLHttpRequest"); var transaction = await SendAsync(server, "http://example.com/forbid?X-Requested-With=XMLHttpRequest");
Assert.Equal(HttpStatusCode.Forbidden, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.Forbidden, transaction.Response.StatusCode);
var responded = transaction.Response.Headers.GetValues("Location"); var responded = transaction.Response.Headers.GetValues("Location");
@ -67,7 +71,8 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
[Fact] [Fact]
public async Task AjaxLogoutRedirectToReturnUrlTurnsInto200WithLocationHeader() public async Task AjaxLogoutRedirectToReturnUrlTurnsInto200WithLocationHeader()
{ {
var server = CreateServer(o => o.LogoutPath = "/signout"); using var host = await CreateHost(o => o.LogoutPath = "/signout");
using var server = host.GetTestServer();
var transaction = await SendAsync(server, "http://example.com/signout?X-Requested-With=XMLHttpRequest&ReturnUrl=/"); var transaction = await SendAsync(server, "http://example.com/signout?X-Requested-With=XMLHttpRequest&ReturnUrl=/");
Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode);
var responded = transaction.Response.Headers.GetValues("Location"); var responded = transaction.Response.Headers.GetValues("Location");
@ -78,7 +83,8 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
[Fact] [Fact]
public async Task AjaxChallengeRedirectTurnsInto200WithLocationHeader() public async Task AjaxChallengeRedirectTurnsInto200WithLocationHeader()
{ {
var server = CreateServer(s => { }); using var host = await CreateHost(s => { });
using var server = host.GetTestServer();
var transaction = await SendAsync(server, "http://example.com/challenge?X-Requested-With=XMLHttpRequest&ReturnUrl=/"); var transaction = await SendAsync(server, "http://example.com/challenge?X-Requested-With=XMLHttpRequest&ReturnUrl=/");
Assert.Equal(HttpStatusCode.Unauthorized, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.Unauthorized, transaction.Response.StatusCode);
var responded = transaction.Response.Headers.GetValues("Location"); var responded = transaction.Response.Headers.GetValues("Location");
@ -89,7 +95,8 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
[Fact] [Fact]
public async Task ProtectedCustomRequestShouldRedirectToCustomRedirectUri() public async Task ProtectedCustomRequestShouldRedirectToCustomRedirectUri()
{ {
var server = CreateServer(s => { }); using var host = await CreateHost(s => { });
using var server = host.GetTestServer();
var transaction = await SendAsync(server, "http://example.com/protected/CustomRedirect"); var transaction = await SendAsync(server, "http://example.com/protected/CustomRedirect");
@ -122,12 +129,13 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
[Fact] [Fact]
public async Task SignInCausesDefaultCookieToBeCreated() public async Task SignInCausesDefaultCookieToBeCreated()
{ {
var server = CreateServerWithServices(s => s.AddAuthentication().AddCookie(o => using var host = await CreateHostWithServices(s => s.AddAuthentication().AddCookie(o =>
{ {
o.LoginPath = new PathString("/login"); o.LoginPath = new PathString("/login");
o.Cookie.Name = "TestCookie"; o.Cookie.Name = "TestCookie";
}), SignInAsAlice); }), SignInAsAlice);
using var server = host.GetTestServer();
var transaction = await SendAsync(server, "http://example.com/testpath"); var transaction = await SendAsync(server, "http://example.com/testpath");
var setCookie = transaction.SetCookie; var setCookie = transaction.SetCookie;
@ -158,11 +166,12 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
[Fact] [Fact]
public async Task SignInWrongAuthTypeThrows() public async Task SignInWrongAuthTypeThrows()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.LoginPath = new PathString("/login"); o.LoginPath = new PathString("/login");
o.Cookie.Name = "TestCookie"; o.Cookie.Name = "TestCookie";
}, SignInAsWrong); }, SignInAsWrong);
using var server = host.GetTestServer();
await Assert.ThrowsAsync<InvalidOperationException>(async () => await SendAsync(server, "http://example.com/testpath")); await Assert.ThrowsAsync<InvalidOperationException>(async () => await SendAsync(server, "http://example.com/testpath"));
} }
@ -170,12 +179,13 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
[Fact] [Fact]
public async Task SignOutWrongAuthTypeThrows() public async Task SignOutWrongAuthTypeThrows()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.LoginPath = new PathString("/login"); o.LoginPath = new PathString("/login");
o.Cookie.Name = "TestCookie"; o.Cookie.Name = "TestCookie";
}, SignOutAsWrong); }, SignOutAsWrong);
using var server = host.GetTestServer();
await Assert.ThrowsAsync<InvalidOperationException>(async () => await SendAsync(server, "http://example.com/testpath")); await Assert.ThrowsAsync<InvalidOperationException>(async () => await SendAsync(server, "http://example.com/testpath"));
} }
@ -191,13 +201,14 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
string requestUri, string requestUri,
bool shouldBeSecureOnly) bool shouldBeSecureOnly)
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.LoginPath = new PathString("/login"); o.LoginPath = new PathString("/login");
o.Cookie.Name = "TestCookie"; o.Cookie.Name = "TestCookie";
o.Cookie.SecurePolicy = cookieSecurePolicy; o.Cookie.SecurePolicy = cookieSecurePolicy;
}, SignInAsAlice); }, SignInAsAlice);
using var server = host.GetTestServer();
var transaction = await SendAsync(server, requestUri); var transaction = await SendAsync(server, requestUri);
var setCookie = transaction.SetCookie; var setCookie = transaction.SetCookie;
@ -214,7 +225,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
[Fact] [Fact]
public async Task CookieOptionsAlterSetCookieHeader() public async Task CookieOptionsAlterSetCookieHeader()
{ {
var server1 = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.Cookie.Name = "TestCookie"; o.Cookie.Name = "TestCookie";
o.Cookie.Path = "/foo"; o.Cookie.Path = "/foo";
@ -224,6 +235,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
o.Cookie.HttpOnly = true; o.Cookie.HttpOnly = true;
}, SignInAsAlice, baseAddress: new Uri("http://example.com/base")); }, SignInAsAlice, baseAddress: new Uri("http://example.com/base"));
using var server1 = host.GetTestServer();
var transaction1 = await SendAsync(server1, "http://example.com/base/testpath"); var transaction1 = await SendAsync(server1, "http://example.com/base/testpath");
var setCookie1 = transaction1.SetCookie; var setCookie1 = transaction1.SetCookie;
@ -235,7 +247,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
Assert.Contains(" samesite=none", setCookie1); Assert.Contains(" samesite=none", setCookie1);
Assert.Contains(" httponly", setCookie1); Assert.Contains(" httponly", setCookie1);
var server2 = CreateServer(o => using var host2 = await CreateHost(o =>
{ {
o.Cookie.Name = "SecondCookie"; o.Cookie.Name = "SecondCookie";
o.Cookie.SecurePolicy = CookieSecurePolicy.None; o.Cookie.SecurePolicy = CookieSecurePolicy.None;
@ -243,6 +255,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
o.Cookie.HttpOnly = false; o.Cookie.HttpOnly = false;
}, SignInAsAlice, baseAddress: new Uri("http://example.com/base")); }, SignInAsAlice, baseAddress: new Uri("http://example.com/base"));
using var server2 = host2.GetTestServer();
var transaction2 = await SendAsync(server2, "http://example.com/base/testpath"); var transaction2 = await SendAsync(server2, "http://example.com/base/testpath");
var setCookie2 = transaction2.SetCookie; var setCookie2 = transaction2.SetCookie;
@ -258,7 +271,8 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
[Fact] [Fact]
public async Task CookieContainsIdentity() public async Task CookieContainsIdentity()
{ {
var server = CreateServer(o => { }, SignInAsAlice); using var host = await CreateHost(o => { }, SignInAsAlice);
using var server = host.GetTestServer();
var transaction1 = await SendAsync(server, "http://example.com/testpath"); var transaction1 = await SendAsync(server, "http://example.com/testpath");
@ -270,11 +284,12 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
[Fact] [Fact]
public async Task CookieAppliesClaimsTransform() public async Task CookieAppliesClaimsTransform()
{ {
var server = CreateServer(o => { }, using var host = await CreateHost(o => { },
SignInAsAlice, SignInAsAlice,
baseAddress: null, baseAddress: null,
claimsTransform: true); claimsTransform: true);
using var server = host.GetTestServer();
var transaction1 = await SendAsync(server, "http://example.com/testpath"); var transaction1 = await SendAsync(server, "http://example.com/testpath");
var transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); var transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue);
@ -287,12 +302,13 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
[Fact] [Fact]
public async Task CookieStopsWorkingAfterExpiration() public async Task CookieStopsWorkingAfterExpiration()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ExpireTimeSpan = TimeSpan.FromMinutes(10); o.ExpireTimeSpan = TimeSpan.FromMinutes(10);
o.SlidingExpiration = false; o.SlidingExpiration = false;
}, SignInAsAlice); }, SignInAsAlice);
using var server = host.GetTestServer();
var transaction1 = await SendAsync(server, "http://example.com/testpath"); var transaction1 = await SendAsync(server, "http://example.com/testpath");
var transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); var transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue);
@ -316,7 +332,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
[Fact] [Fact]
public async Task CookieExpirationCanBeOverridenInSignin() public async Task CookieExpirationCanBeOverridenInSignin()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ExpireTimeSpan = TimeSpan.FromMinutes(10); o.ExpireTimeSpan = TimeSpan.FromMinutes(10);
o.SlidingExpiration = false; o.SlidingExpiration = false;
@ -326,6 +342,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
new ClaimsPrincipal(new ClaimsIdentity(new GenericIdentity("Alice", "Cookies"))), new ClaimsPrincipal(new ClaimsIdentity(new GenericIdentity("Alice", "Cookies"))),
new AuthenticationProperties() { ExpiresUtc = _clock.UtcNow.Add(TimeSpan.FromMinutes(5)) })); new AuthenticationProperties() { ExpiresUtc = _clock.UtcNow.Add(TimeSpan.FromMinutes(5)) }));
using var server = host.GetTestServer();
var transaction1 = await SendAsync(server, "http://example.com/testpath"); var transaction1 = await SendAsync(server, "http://example.com/testpath");
var transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); var transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue);
@ -349,7 +366,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
[Fact] [Fact]
public async Task ExpiredCookieWithValidatorStillExpired() public async Task ExpiredCookieWithValidatorStillExpired()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ExpireTimeSpan = TimeSpan.FromMinutes(10); o.ExpireTimeSpan = TimeSpan.FromMinutes(10);
o.Events = new CookieAuthenticationEvents o.Events = new CookieAuthenticationEvents
@ -365,6 +382,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
context.SignInAsync("Cookies", context.SignInAsync("Cookies",
new ClaimsPrincipal(new ClaimsIdentity(new GenericIdentity("Alice", "Cookies"))))); new ClaimsPrincipal(new ClaimsIdentity(new GenericIdentity("Alice", "Cookies")))));
using var server = host.GetTestServer();
var transaction1 = await SendAsync(server, "http://example.com/testpath"); var transaction1 = await SendAsync(server, "http://example.com/testpath");
_clock.Add(TimeSpan.FromMinutes(11)); _clock.Add(TimeSpan.FromMinutes(11));
@ -377,7 +395,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
[Fact] [Fact]
public async Task CookieCanBeRejectedAndSignedOutByValidator() public async Task CookieCanBeRejectedAndSignedOutByValidator()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ExpireTimeSpan = TimeSpan.FromMinutes(10); o.ExpireTimeSpan = TimeSpan.FromMinutes(10);
o.SlidingExpiration = false; o.SlidingExpiration = false;
@ -395,6 +413,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
context.SignInAsync("Cookies", context.SignInAsync("Cookies",
new ClaimsPrincipal(new ClaimsIdentity(new GenericIdentity("Alice", "Cookies"))))); new ClaimsPrincipal(new ClaimsIdentity(new GenericIdentity("Alice", "Cookies")))));
using var server = host.GetTestServer();
var transaction1 = await SendAsync(server, "http://example.com/testpath"); var transaction1 = await SendAsync(server, "http://example.com/testpath");
var transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); var transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue);
@ -405,7 +424,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
[Fact] [Fact]
public async Task CookieNotRenewedAfterSignOut() public async Task CookieNotRenewedAfterSignOut()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ExpireTimeSpan = TimeSpan.FromMinutes(10); o.ExpireTimeSpan = TimeSpan.FromMinutes(10);
o.SlidingExpiration = false; o.SlidingExpiration = false;
@ -422,6 +441,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
context.SignInAsync("Cookies", context.SignInAsync("Cookies",
new ClaimsPrincipal(new ClaimsIdentity(new GenericIdentity("Alice", "Cookies"))))); new ClaimsPrincipal(new ClaimsIdentity(new GenericIdentity("Alice", "Cookies")))));
using var server = host.GetTestServer();
var transaction1 = await SendAsync(server, "http://example.com/testpath"); var transaction1 = await SendAsync(server, "http://example.com/testpath");
// renews on every request // renews on every request
@ -441,7 +461,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
[Fact] [Fact]
public async Task CookieCanBeRenewedByValidator() public async Task CookieCanBeRenewedByValidator()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ExpireTimeSpan = TimeSpan.FromMinutes(10); o.ExpireTimeSpan = TimeSpan.FromMinutes(10);
o.SlidingExpiration = false; o.SlidingExpiration = false;
@ -458,6 +478,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
context.SignInAsync("Cookies", context.SignInAsync("Cookies",
new ClaimsPrincipal(new ClaimsIdentity(new GenericIdentity("Alice", "Cookies"))))); new ClaimsPrincipal(new ClaimsIdentity(new GenericIdentity("Alice", "Cookies")))));
using var server = host.GetTestServer();
var transaction1 = await SendAsync(server, "http://example.com/testpath"); var transaction1 = await SendAsync(server, "http://example.com/testpath");
var transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); var transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue);
@ -486,7 +507,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
[Fact] [Fact]
public async Task CookieCanBeReplacedByValidator() public async Task CookieCanBeReplacedByValidator()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.Events = new CookieAuthenticationEvents o.Events = new CookieAuthenticationEvents
{ {
@ -502,6 +523,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
context.SignInAsync("Cookies", context.SignInAsync("Cookies",
new ClaimsPrincipal(new ClaimsIdentity(new GenericIdentity("Alice", "Cookies"))))); new ClaimsPrincipal(new ClaimsIdentity(new GenericIdentity("Alice", "Cookies")))));
using var server = host.GetTestServer();
var transaction1 = await SendAsync(server, "http://example.com/testpath"); var transaction1 = await SendAsync(server, "http://example.com/testpath");
var transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); var transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue);
@ -513,7 +535,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
public async Task CookieCanBeUpdatedByValidatorDuringRefresh() public async Task CookieCanBeUpdatedByValidatorDuringRefresh()
{ {
var replace = false; var replace = false;
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ExpireTimeSpan = TimeSpan.FromMinutes(10); o.ExpireTimeSpan = TimeSpan.FromMinutes(10);
o.Events = new CookieAuthenticationEvents o.Events = new CookieAuthenticationEvents
@ -534,6 +556,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
context.SignInAsync("Cookies", context.SignInAsync("Cookies",
new ClaimsPrincipal(new ClaimsIdentity(new GenericIdentity("Alice", "Cookies"))))); new ClaimsPrincipal(new ClaimsIdentity(new GenericIdentity("Alice", "Cookies")))));
using var server = host.GetTestServer();
var transaction1 = await SendAsync(server, "http://example.com/testpath"); var transaction1 = await SendAsync(server, "http://example.com/testpath");
var transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); var transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue);
@ -560,7 +583,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
[Fact] [Fact]
public async Task CookieCanBeRenewedByValidatorWithSlidingExpiry() public async Task CookieCanBeRenewedByValidatorWithSlidingExpiry()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ExpireTimeSpan = TimeSpan.FromMinutes(10); o.ExpireTimeSpan = TimeSpan.FromMinutes(10);
o.Events = new CookieAuthenticationEvents o.Events = new CookieAuthenticationEvents
@ -576,6 +599,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
context.SignInAsync("Cookies", context.SignInAsync("Cookies",
new ClaimsPrincipal(new ClaimsIdentity(new GenericIdentity("Alice", "Cookies"))))); new ClaimsPrincipal(new ClaimsIdentity(new GenericIdentity("Alice", "Cookies")))));
using var server = host.GetTestServer();
var transaction1 = await SendAsync(server, "http://example.com/testpath"); var transaction1 = await SendAsync(server, "http://example.com/testpath");
var transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); var transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue);
@ -604,7 +628,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
[Fact] [Fact]
public async Task CookieCanBeRenewedByValidatorWithModifiedProperties() public async Task CookieCanBeRenewedByValidatorWithModifiedProperties()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ExpireTimeSpan = TimeSpan.FromMinutes(10); o.ExpireTimeSpan = TimeSpan.FromMinutes(10);
o.Events = new CookieAuthenticationEvents o.Events = new CookieAuthenticationEvents
@ -631,6 +655,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
context.SignInAsync("Cookies", context.SignInAsync("Cookies",
new ClaimsPrincipal(new ClaimsIdentity(new GenericIdentity("Alice", "Cookies"))))); new ClaimsPrincipal(new ClaimsIdentity(new GenericIdentity("Alice", "Cookies")))));
using var server = host.GetTestServer();
var transaction1 = await SendAsync(server, "http://example.com/testpath"); var transaction1 = await SendAsync(server, "http://example.com/testpath");
var transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); var transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue);
@ -659,7 +684,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
[Fact] [Fact]
public async Task CookieValidatorOnlyCalledOnce() public async Task CookieValidatorOnlyCalledOnce()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ExpireTimeSpan = TimeSpan.FromMinutes(10); o.ExpireTimeSpan = TimeSpan.FromMinutes(10);
o.SlidingExpiration = false; o.SlidingExpiration = false;
@ -676,6 +701,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
context.SignInAsync("Cookies", context.SignInAsync("Cookies",
new ClaimsPrincipal(new ClaimsIdentity(new GenericIdentity("Alice", "Cookies"))))); new ClaimsPrincipal(new ClaimsIdentity(new GenericIdentity("Alice", "Cookies")))));
using var server = host.GetTestServer();
var transaction1 = await SendAsync(server, "http://example.com/testpath"); var transaction1 = await SendAsync(server, "http://example.com/testpath");
var transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); var transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue);
@ -708,7 +734,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
{ {
DateTimeOffset? lastValidateIssuedDate = null; DateTimeOffset? lastValidateIssuedDate = null;
DateTimeOffset? lastExpiresDate = null; DateTimeOffset? lastExpiresDate = null;
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ExpireTimeSpan = TimeSpan.FromMinutes(10); o.ExpireTimeSpan = TimeSpan.FromMinutes(10);
o.SlidingExpiration = sliding; o.SlidingExpiration = sliding;
@ -727,6 +753,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
context.SignInAsync("Cookies", context.SignInAsync("Cookies",
new ClaimsPrincipal(new ClaimsIdentity(new GenericIdentity("Alice", "Cookies"))))); new ClaimsPrincipal(new ClaimsIdentity(new GenericIdentity("Alice", "Cookies")))));
using var server = host.GetTestServer();
var transaction1 = await SendAsync(server, "http://example.com/testpath"); var transaction1 = await SendAsync(server, "http://example.com/testpath");
var transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); var transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue);
@ -758,7 +785,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
[Fact] [Fact]
public async Task CookieExpirationCanBeOverridenInEvent() public async Task CookieExpirationCanBeOverridenInEvent()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ExpireTimeSpan = TimeSpan.FromMinutes(10); o.ExpireTimeSpan = TimeSpan.FromMinutes(10);
o.SlidingExpiration = false; o.SlidingExpiration = false;
@ -773,6 +800,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
}, },
SignInAsAlice); SignInAsAlice);
using var server = host.GetTestServer();
var transaction1 = await SendAsync(server, "http://example.com/testpath"); var transaction1 = await SendAsync(server, "http://example.com/testpath");
var transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); var transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue);
@ -795,13 +823,14 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
[Fact] [Fact]
public async Task CookieIsRenewedWithSlidingExpiration() public async Task CookieIsRenewedWithSlidingExpiration()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ExpireTimeSpan = TimeSpan.FromMinutes(10); o.ExpireTimeSpan = TimeSpan.FromMinutes(10);
o.SlidingExpiration = true; o.SlidingExpiration = true;
}, },
SignInAsAlice); SignInAsAlice);
using var server = host.GetTestServer();
var transaction1 = await SendAsync(server, "http://example.com/testpath"); var transaction1 = await SendAsync(server, "http://example.com/testpath");
var transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); var transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue);
@ -831,7 +860,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
[Fact] [Fact]
public async Task CookieIsRenewedWithSlidingExpirationWithoutTransformations() public async Task CookieIsRenewedWithSlidingExpirationWithoutTransformations()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ExpireTimeSpan = TimeSpan.FromMinutes(10); o.ExpireTimeSpan = TimeSpan.FromMinutes(10);
o.SlidingExpiration = true; o.SlidingExpiration = true;
@ -847,6 +876,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
SignInAsAlice, SignInAsAlice,
claimsTransform: true); claimsTransform: true);
using var server = host.GetTestServer();
var transaction1 = await SendAsync(server, "http://example.com/testpath"); var transaction1 = await SendAsync(server, "http://example.com/testpath");
var transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue); var transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue);
@ -876,7 +906,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
[Fact] [Fact]
public async Task CookieUsesPathBaseByDefault() public async Task CookieUsesPathBaseByDefault()
{ {
var server = CreateServer(o => { }, using var host = await CreateHost(o => { },
context => context =>
{ {
Assert.Equal(new PathString("/base"), context.Request.PathBase); Assert.Equal(new PathString("/base"), context.Request.PathBase);
@ -885,6 +915,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
}, },
new Uri("http://example.com/base")); new Uri("http://example.com/base"));
using var server = host.GetTestServer();
var transaction1 = await SendAsync(server, "http://example.com/base/testpath"); var transaction1 = await SendAsync(server, "http://example.com/base/testpath");
Assert.Contains("path=/base", transaction1.SetCookie); Assert.Contains("path=/base", transaction1.SetCookie);
} }
@ -892,9 +923,10 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
[Fact] [Fact]
public async Task CookieChallengeRedirectsToLoginWithoutCookie() public async Task CookieChallengeRedirectsToLoginWithoutCookie()
{ {
var server = CreateServer(o => { }, SignInAsAlice); using var host = await CreateHost(o => { }, SignInAsAlice);
var url = "http://example.com/challenge"; var url = "http://example.com/challenge";
using var server = host.GetTestServer();
var transaction = await SendAsync(server, url); var transaction = await SendAsync(server, url);
Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
@ -905,9 +937,10 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
[Fact] [Fact]
public async Task CookieForbidRedirectsWithoutCookie() public async Task CookieForbidRedirectsWithoutCookie()
{ {
var server = CreateServer(o => { }, SignInAsAlice); using var host = await CreateHost(o => { }, SignInAsAlice);
var url = "http://example.com/forbid"; var url = "http://example.com/forbid";
using var server = host.GetTestServer();
var transaction = await SendAsync(server, url); var transaction = await SendAsync(server, url);
Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
@ -918,10 +951,11 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
[Fact] [Fact]
public async Task CookieChallengeRedirectsWithLoginPath() public async Task CookieChallengeRedirectsWithLoginPath()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.LoginPath = new PathString("/page"); o.LoginPath = new PathString("/page");
}); });
using var server = host.GetTestServer();
var transaction1 = await SendAsync(server, "http://example.com/testpath"); var transaction1 = await SendAsync(server, "http://example.com/testpath");
@ -933,10 +967,11 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
[Fact] [Fact]
public async Task CookieChallengeWithUnauthorizedRedirectsToLoginIfNotAuthenticated() public async Task CookieChallengeWithUnauthorizedRedirectsToLoginIfNotAuthenticated()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.LoginPath = new PathString("/page"); o.LoginPath = new PathString("/page");
}); });
using var server = host.GetTestServer();
var transaction1 = await SendAsync(server, "http://example.com/testpath"); var transaction1 = await SendAsync(server, "http://example.com/testpath");
@ -950,7 +985,9 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
[InlineData(false)] [InlineData(false)]
public async Task MapWillAffectChallengeOnlyWithUseAuth(bool useAuth) public async Task MapWillAffectChallengeOnlyWithUseAuth(bool useAuth)
{ {
var builder = new WebHostBuilder() using var host = new HostBuilder()
.ConfigureWebHost(builder =>
builder.UseTestServer()
.Configure(app => .Configure(app =>
{ {
if (useAuth) if (useAuth)
@ -959,8 +996,10 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
} }
app.Map("/login", signoutApp => signoutApp.Run(context => context.ChallengeAsync("Cookies", new AuthenticationProperties() { RedirectUri = "/" }))); app.Map("/login", signoutApp => signoutApp.Run(context => context.ChallengeAsync("Cookies", new AuthenticationProperties() { RedirectUri = "/" })));
}) })
.ConfigureServices(s => s.AddAuthentication().AddCookie(o => o.LoginPath = new PathString("/page"))); .ConfigureServices(s => s.AddAuthentication().AddCookie(o => o.LoginPath = new PathString("/page"))))
var server = new TestServer(builder); .Build();
await host.StartAsync();
using var server = host.GetTestServer();
var transaction = await server.SendAsync("http://example.com/login"); var transaction = await server.SendAsync("http://example.com/login");
@ -981,7 +1020,9 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
[ConditionalFact(Skip = "Revisit, exception no longer thrown")] [ConditionalFact(Skip = "Revisit, exception no longer thrown")]
public async Task ChallengeDoesNotSet401OnUnauthorized() public async Task ChallengeDoesNotSet401OnUnauthorized()
{ {
var builder = new WebHostBuilder() using var host = new HostBuilder()
.ConfigureWebHost(builder =>
builder.UseTestServer()
.Configure(app => .Configure(app =>
{ {
app.UseAuthentication(); app.UseAuthentication();
@ -990,8 +1031,11 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
await Assert.ThrowsAsync<InvalidOperationException>(() => context.ChallengeAsync(CookieAuthenticationDefaults.AuthenticationScheme)); await Assert.ThrowsAsync<InvalidOperationException>(() => context.ChallengeAsync(CookieAuthenticationDefaults.AuthenticationScheme));
}); });
}) })
.ConfigureServices(services => services.AddAuthentication().AddCookie()); .ConfigureServices(services => services.AddAuthentication().AddCookie()))
var server = new TestServer(builder); .Build();
await host.StartAsync();
using var server = host.GetTestServer();
var transaction = await server.SendAsync("http://example.com"); var transaction = await server.SendAsync("http://example.com");
Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode);
@ -1000,7 +1044,9 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
[Fact] [Fact]
public async Task CanConfigureDefaultCookieInstance() public async Task CanConfigureDefaultCookieInstance()
{ {
var builder = new WebHostBuilder() using var host = new HostBuilder()
.ConfigureWebHost(builder =>
builder.UseTestServer()
.Configure(app => .Configure(app =>
{ {
app.UseAuthentication(); app.UseAuthentication();
@ -1011,8 +1057,11 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
services.AddAuthentication().AddCookie(); services.AddAuthentication().AddCookie();
services.Configure<CookieAuthenticationOptions>(CookieAuthenticationDefaults.AuthenticationScheme, services.Configure<CookieAuthenticationOptions>(CookieAuthenticationDefaults.AuthenticationScheme,
o => o.Cookie.Name = "One"); o => o.Cookie.Name = "One");
}); }))
var server = new TestServer(builder); .Build();
await host.StartAsync();
using var server = host.GetTestServer();
var transaction = await server.SendAsync("http://example.com"); var transaction = await server.SendAsync("http://example.com");
@ -1023,7 +1072,9 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
[Fact] [Fact]
public async Task CanConfigureNamedCookieInstance() public async Task CanConfigureNamedCookieInstance()
{ {
var builder = new WebHostBuilder() using var host = new HostBuilder()
.ConfigureWebHost(builder =>
builder.UseTestServer()
.Configure(app => .Configure(app =>
{ {
app.UseAuthentication(); app.UseAuthentication();
@ -1034,8 +1085,11 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
services.AddAuthentication().AddCookie("Cookie1"); services.AddAuthentication().AddCookie("Cookie1");
services.Configure<CookieAuthenticationOptions>("Cookie1", services.Configure<CookieAuthenticationOptions>("Cookie1",
o => o.Cookie.Name = "One"); o => o.Cookie.Name = "One");
}); }))
var server = new TestServer(builder); .Build();
await host.StartAsync();
using var server = host.GetTestServer();
var transaction = await server.SendAsync("http://example.com"); var transaction = await server.SendAsync("http://example.com");
@ -1046,15 +1100,20 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
[Fact] [Fact]
public async Task MapWithSignInOnlyRedirectToReturnUrlOnLoginPath() public async Task MapWithSignInOnlyRedirectToReturnUrlOnLoginPath()
{ {
var builder = new WebHostBuilder() using var host = new HostBuilder()
.ConfigureWebHost(builder =>
builder.UseTestServer()
.Configure(app => .Configure(app =>
{ {
app.UseAuthentication(); app.UseAuthentication();
app.Map("/notlogin", signoutApp => signoutApp.Run(context => context.SignInAsync("Cookies", app.Map("/notlogin", signoutApp => signoutApp.Run(context => context.SignInAsync("Cookies",
new ClaimsPrincipal(new ClaimsIdentity("whatever"))))); new ClaimsPrincipal(new ClaimsIdentity("whatever")))));
}) })
.ConfigureServices(services => services.AddAuthentication().AddCookie(o => o.LoginPath = new PathString("/login"))); .ConfigureServices(services => services.AddAuthentication().AddCookie(o => o.LoginPath = new PathString("/login"))))
var server = new TestServer(builder); .Build();
await host.StartAsync();
using var server = host.GetTestServer();
var transaction = await server.SendAsync("http://example.com/notlogin?ReturnUrl=%2Fpage"); var transaction = await server.SendAsync("http://example.com/notlogin?ReturnUrl=%2Fpage");
Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode);
@ -1064,15 +1123,19 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
[Fact] [Fact]
public async Task MapWillNotAffectSignInRedirectToReturnUrl() public async Task MapWillNotAffectSignInRedirectToReturnUrl()
{ {
var builder = new WebHostBuilder() using var host = new HostBuilder()
.ConfigureWebHost(builder =>
builder.UseTestServer()
.Configure(app => .Configure(app =>
{ {
app.UseAuthentication(); app.UseAuthentication();
app.Map("/login", signoutApp => signoutApp.Run(context => context.SignInAsync("Cookies", new ClaimsPrincipal(new ClaimsIdentity("whatever"))))); app.Map("/login", signoutApp => signoutApp.Run(context => context.SignInAsync("Cookies", new ClaimsPrincipal(new ClaimsIdentity("whatever")))));
}) })
.ConfigureServices(services => services.AddAuthentication().AddCookie(o => o.LoginPath = new PathString("/login"))); .ConfigureServices(services => services.AddAuthentication().AddCookie(o => o.LoginPath = new PathString("/login"))))
.Build();
var server = new TestServer(builder); await host.StartAsync();
using var server = host.GetTestServer();
var transaction = await server.SendAsync("http://example.com/login?ReturnUrl=%2Fpage"); var transaction = await server.SendAsync("http://example.com/login?ReturnUrl=%2Fpage");
@ -1086,14 +1149,19 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
[Fact] [Fact]
public async Task MapWithSignOutOnlyRedirectToReturnUrlOnLogoutPath() public async Task MapWithSignOutOnlyRedirectToReturnUrlOnLogoutPath()
{ {
var builder = new WebHostBuilder() using var host = new HostBuilder()
.ConfigureWebHost(builder =>
builder.UseTestServer()
.Configure(app => .Configure(app =>
{ {
app.UseAuthentication(); app.UseAuthentication();
app.Map("/notlogout", signoutApp => signoutApp.Run(context => context.SignOutAsync("Cookies"))); app.Map("/notlogout", signoutApp => signoutApp.Run(context => context.SignOutAsync("Cookies")));
}) })
.ConfigureServices(services => services.AddAuthentication().AddCookie(o => o.LogoutPath = new PathString("/logout"))); .ConfigureServices(services => services.AddAuthentication().AddCookie(o => o.LogoutPath = new PathString("/logout"))))
var server = new TestServer(builder); .Build();
await host.StartAsync();
using var server = host.GetTestServer();
var transaction = await server.SendAsync("http://example.com/notlogout?ReturnUrl=%2Fpage"); var transaction = await server.SendAsync("http://example.com/notlogout?ReturnUrl=%2Fpage");
Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode);
@ -1103,14 +1171,19 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
[Fact] [Fact]
public async Task MapWillNotAffectSignOutRedirectToReturnUrl() public async Task MapWillNotAffectSignOutRedirectToReturnUrl()
{ {
var builder = new WebHostBuilder() using var host = new HostBuilder()
.ConfigureWebHost(builder =>
builder.UseTestServer()
.Configure(app => .Configure(app =>
{ {
app.UseAuthentication(); app.UseAuthentication();
app.Map("/logout", signoutApp => signoutApp.Run(context => context.SignOutAsync("Cookies"))); app.Map("/logout", signoutApp => signoutApp.Run(context => context.SignOutAsync("Cookies")));
}) })
.ConfigureServices(services => services.AddAuthentication().AddCookie(o => o.LogoutPath = new PathString("/logout"))); .ConfigureServices(services => services.AddAuthentication().AddCookie(o => o.LogoutPath = new PathString("/logout"))))
var server = new TestServer(builder); .Build();
await host.StartAsync();
using var server = host.GetTestServer();
var transaction = await server.SendAsync("http://example.com/logout?ReturnUrl=%2Fpage"); var transaction = await server.SendAsync("http://example.com/logout?ReturnUrl=%2Fpage");
@ -1124,14 +1197,19 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
[Fact] [Fact]
public async Task MapWillNotAffectAccessDenied() public async Task MapWillNotAffectAccessDenied()
{ {
var builder = new WebHostBuilder() using var host = new HostBuilder()
.ConfigureWebHost(builder =>
builder.UseTestServer()
.Configure(app => .Configure(app =>
{ {
app.UseAuthentication(); app.UseAuthentication();
app.Map("/forbid", signoutApp => signoutApp.Run(context => context.ForbidAsync("Cookies"))); app.Map("/forbid", signoutApp => signoutApp.Run(context => context.ForbidAsync("Cookies")));
}) })
.ConfigureServices(services => services.AddAuthentication().AddCookie(o => o.AccessDeniedPath = new PathString("/denied"))); .ConfigureServices(services => services.AddAuthentication().AddCookie(o => o.AccessDeniedPath = new PathString("/denied"))))
var server = new TestServer(builder); .Build();
await host.StartAsync();
using var server = host.GetTestServer();
var transaction = await server.SendAsync("http://example.com/forbid"); var transaction = await server.SendAsync("http://example.com/forbid");
Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
@ -1143,15 +1221,20 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
[Fact] [Fact]
public async Task NestedMapWillNotAffectLogin() public async Task NestedMapWillNotAffectLogin()
{ {
var builder = new WebHostBuilder() using var host = new HostBuilder()
.ConfigureWebHost(builder =>
builder.UseTestServer()
.Configure(app => .Configure(app =>
app.Map("/base", map => app.Map("/base", map =>
{ {
map.UseAuthentication(); map.UseAuthentication();
map.Map("/login", signoutApp => signoutApp.Run(context => context.ChallengeAsync("Cookies", new AuthenticationProperties() { RedirectUri = "/" }))); map.Map("/login", signoutApp => signoutApp.Run(context => context.ChallengeAsync("Cookies", new AuthenticationProperties() { RedirectUri = "/" })));
})) }))
.ConfigureServices(services => services.AddAuthentication().AddCookie(o => o.LoginPath = new PathString("/page"))); .ConfigureServices(services => services.AddAuthentication().AddCookie(o => o.LoginPath = new PathString("/page"))))
var server = new TestServer(builder); .Build();
await host.StartAsync();
using var server = host.GetTestServer();
var transaction = await server.SendAsync("http://example.com/base/login"); var transaction = await server.SendAsync("http://example.com/base/login");
Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
@ -1166,7 +1249,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
[InlineData("http://example.com/redirect_to")] [InlineData("http://example.com/redirect_to")]
public async Task RedirectUriIsHoneredAfterSignin(string redirectUrl) public async Task RedirectUriIsHoneredAfterSignin(string redirectUrl)
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.LoginPath = "/testpath"; o.LoginPath = "/testpath";
o.Cookie.Name = "TestCookie"; o.Cookie.Name = "TestCookie";
@ -1177,6 +1260,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
new ClaimsPrincipal(new ClaimsIdentity(new GenericIdentity("Alice", CookieAuthenticationDefaults.AuthenticationScheme))), new ClaimsPrincipal(new ClaimsIdentity(new GenericIdentity("Alice", CookieAuthenticationDefaults.AuthenticationScheme))),
new AuthenticationProperties { RedirectUri = redirectUrl }) new AuthenticationProperties { RedirectUri = redirectUrl })
); );
using var server = host.GetTestServer();
var transaction = await SendAsync(server, "http://example.com/testpath"); var transaction = await SendAsync(server, "http://example.com/testpath");
Assert.NotEmpty(transaction.SetCookie); Assert.NotEmpty(transaction.SetCookie);
@ -1187,7 +1271,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
[Fact] [Fact]
public async Task RedirectUriInQueryIsHoneredAfterSignin() public async Task RedirectUriInQueryIsHoneredAfterSignin()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.LoginPath = "/testpath"; o.LoginPath = "/testpath";
o.ReturnUrlParameter = "return"; o.ReturnUrlParameter = "return";
@ -1199,6 +1283,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
CookieAuthenticationDefaults.AuthenticationScheme, CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(new ClaimsIdentity(new GenericIdentity("Alice", CookieAuthenticationDefaults.AuthenticationScheme)))); new ClaimsPrincipal(new ClaimsIdentity(new GenericIdentity("Alice", CookieAuthenticationDefaults.AuthenticationScheme))));
}); });
using var server = host.GetTestServer();
var transaction = await SendAsync(server, "http://example.com/testpath?return=%2Fret_path_2"); var transaction = await SendAsync(server, "http://example.com/testpath?return=%2Fret_path_2");
Assert.NotEmpty(transaction.SetCookie); Assert.NotEmpty(transaction.SetCookie);
@ -1209,7 +1294,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
[Fact] [Fact]
public async Task AbsoluteRedirectUriInQueryStringIsRejected() public async Task AbsoluteRedirectUriInQueryStringIsRejected()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.LoginPath = "/testpath"; o.LoginPath = "/testpath";
o.ReturnUrlParameter = "return"; o.ReturnUrlParameter = "return";
@ -1221,6 +1306,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
CookieAuthenticationDefaults.AuthenticationScheme, CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(new ClaimsIdentity(new GenericIdentity("Alice", CookieAuthenticationDefaults.AuthenticationScheme)))); new ClaimsPrincipal(new ClaimsIdentity(new GenericIdentity("Alice", CookieAuthenticationDefaults.AuthenticationScheme))));
}); });
using var server = host.GetTestServer();
var transaction = await SendAsync(server, "http://example.com/testpath?return=http%3A%2F%2Fexample.com%2Fredirect_to"); var transaction = await SendAsync(server, "http://example.com/testpath?return=http%3A%2F%2Fexample.com%2Fredirect_to");
Assert.NotEmpty(transaction.SetCookie); Assert.NotEmpty(transaction.SetCookie);
@ -1230,7 +1316,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
[Fact] [Fact]
public async Task EnsurePrecedenceOfRedirectUriAfterSignin() public async Task EnsurePrecedenceOfRedirectUriAfterSignin()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.LoginPath = "/testpath"; o.LoginPath = "/testpath";
o.ReturnUrlParameter = "return"; o.ReturnUrlParameter = "return";
@ -1243,6 +1329,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
new ClaimsPrincipal(new ClaimsIdentity(new GenericIdentity("Alice", CookieAuthenticationDefaults.AuthenticationScheme))), new ClaimsPrincipal(new ClaimsIdentity(new GenericIdentity("Alice", CookieAuthenticationDefaults.AuthenticationScheme))),
new AuthenticationProperties { RedirectUri = "/redirect_test" }); new AuthenticationProperties { RedirectUri = "/redirect_test" });
}); });
using var server = host.GetTestServer();
var transaction = await SendAsync(server, "http://example.com/testpath?return=%2Fret_path_2"); var transaction = await SendAsync(server, "http://example.com/testpath?return=%2Fret_path_2");
Assert.NotEmpty(transaction.SetCookie); Assert.NotEmpty(transaction.SetCookie);
@ -1253,15 +1340,19 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
[Fact] [Fact]
public async Task NestedMapWillNotAffectAccessDenied() public async Task NestedMapWillNotAffectAccessDenied()
{ {
var builder = new WebHostBuilder() using var host = new HostBuilder()
.ConfigureWebHost(builder =>
builder.UseTestServer()
.Configure(app => .Configure(app =>
app.Map("/base", map => app.Map("/base", map =>
{ {
map.UseAuthentication(); map.UseAuthentication();
map.Map("/forbid", signoutApp => signoutApp.Run(context => context.ForbidAsync("Cookies"))); map.Map("/forbid", signoutApp => signoutApp.Run(context => context.ForbidAsync("Cookies")));
})) }))
.ConfigureServices(services => services.AddAuthentication().AddCookie(o => o.AccessDeniedPath = new PathString("/denied"))); .ConfigureServices(services => services.AddAuthentication().AddCookie(o => o.AccessDeniedPath = new PathString("/denied"))))
var server = new TestServer(builder); .Build();
await host.StartAsync();
using var server = host.GetTestServer();
var transaction = await server.SendAsync("http://example.com/base/forbid"); var transaction = await server.SendAsync("http://example.com/base/forbid");
Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
@ -1273,9 +1364,10 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
[Fact] [Fact]
public async Task CanSpecifyAndShareDataProtector() public async Task CanSpecifyAndShareDataProtector()
{ {
var dp = new NoOpDataProtector(); var dp = new NoOpDataProtector();
var builder1 = new WebHostBuilder() using var host1 = new HostBuilder()
.ConfigureWebHost(builder =>
builder.UseTestServer()
.Configure(app => .Configure(app =>
{ {
app.UseAuthentication(); app.UseAuthentication();
@ -1288,13 +1380,17 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
{ {
o.TicketDataFormat = new TicketDataFormat(dp); o.TicketDataFormat = new TicketDataFormat(dp);
o.Cookie.Name = "Cookie"; o.Cookie.Name = "Cookie";
})); })))
var server1 = new TestServer(builder1); .Build();
await host1.StartAsync();
using var server1 = host1.GetTestServer(); ;
var transaction = await SendAsync(server1, "http://example.com/stuff"); var transaction = await SendAsync(server1, "http://example.com/stuff");
Assert.NotNull(transaction.SetCookie); Assert.NotNull(transaction.SetCookie);
var builder2 = new WebHostBuilder() using var host2 = new HostBuilder()
.ConfigureWebHost(builder =>
builder.UseTestServer()
.Configure(app => .Configure(app =>
{ {
app.UseAuthentication(); app.UseAuthentication();
@ -1308,8 +1404,10 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
{ {
o.Cookie.Name = "Cookie"; o.Cookie.Name = "Cookie";
o.TicketDataFormat = new TicketDataFormat(dp); o.TicketDataFormat = new TicketDataFormat(dp);
})); })))
var server2 = new TestServer(builder2); .Build();
await host2.StartAsync();
using var server2 = host2.GetTestServer();
var transaction2 = await SendAsync(server2, "http://example.com/stuff", transaction.CookieNameValue); var transaction2 = await SendAsync(server2, "http://example.com/stuff", transaction.CookieNameValue);
Assert.Equal("Alice", FindClaimValue(transaction2, ClaimTypes.Name)); Assert.Equal("Alice", FindClaimValue(transaction2, ClaimTypes.Name));
} }
@ -1318,7 +1416,9 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
[Fact] [Fact]
public async Task NullExpiresUtcPropertyIsGuarded() public async Task NullExpiresUtcPropertyIsGuarded()
{ {
var builder = new WebHostBuilder() using var host = new HostBuilder()
.ConfigureWebHost(builder =>
builder.UseTestServer()
.ConfigureServices(services => services.AddAuthentication().AddCookie(o => .ConfigureServices(services => services.AddAuthentication().AddCookie(o =>
{ {
o.Events = new CookieAuthenticationEvents o.Events = new CookieAuthenticationEvents
@ -1348,9 +1448,11 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
await context.Response.WriteAsync("ha+1"); await context.Response.WriteAsync("ha+1");
} }
}); });
}); }))
.Build();
var server = new TestServer(builder); await host.StartAsync();
using var server = host.GetTestServer();
var cookie = (await server.SendAsync("http://www.example.com/signin")).SetCookie.FirstOrDefault(); var cookie = (await server.SendAsync("http://www.example.com/signin")).SetCookie.FirstOrDefault();
Assert.NotNull(cookie); Assert.NotNull(cookie);
@ -1429,8 +1531,8 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
} }
} }
private TestServer CreateServer(Action<CookieAuthenticationOptions> configureOptions, Func<HttpContext, Task> testpath = null, Uri baseAddress = null, bool claimsTransform = false) private Task<IHost> CreateHost(Action<CookieAuthenticationOptions> configureOptions, Func<HttpContext, Task> testpath = null, Uri baseAddress = null, bool claimsTransform = false)
=> CreateServerWithServices(s => => CreateHostWithServices(s =>
{ {
s.AddSingleton<ISystemClock>(_clock); s.AddSingleton<ISystemClock>(_clock);
s.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(configureOptions); s.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(configureOptions);
@ -1440,9 +1542,11 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
} }
}, testpath, baseAddress); }, testpath, baseAddress);
private static TestServer CreateServerWithServices(Action<IServiceCollection> configureServices, Func<HttpContext, Task> testpath = null, Uri baseAddress = null) private static async Task<IHost> CreateHostWithServices(Action<IServiceCollection> configureServices, Func<HttpContext, Task> testpath = null, Uri baseAddress = null)
{ {
var builder = new WebHostBuilder() var host = new HostBuilder()
.ConfigureWebHost(builder =>
builder.UseTestServer()
.Configure(app => .Configure(app =>
{ {
app.UseAuthentication(); app.UseAuthentication();
@ -1503,10 +1607,14 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
} }
}); });
}) })
.ConfigureServices(configureServices); .ConfigureServices(configureServices))
var server = new TestServer(builder); .Build();
await host.StartAsync();
var server = host.GetTestServer();
server.BaseAddress = baseAddress; server.BaseAddress = baseAddress;
return server; return host;
} }
private static Task DescribeAsync(HttpResponse res, AuthenticateResult result) private static Task DescribeAsync(HttpResponse res, AuthenticateResult result)

View File

@ -10,6 +10,7 @@ using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.TestHost; using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Xunit; using Xunit;
@ -21,12 +22,13 @@ namespace Microsoft.AspNetCore.Authentication
[Fact] [Fact]
public async Task OptionsAreConfiguredOnce() public async Task OptionsAreConfiguredOnce()
{ {
var server = CreateServer(s => using var host = await CreateHost(s =>
{ {
s.Configure<TestOptions>("One", o => o.Instance = new Singleton()); s.Configure<TestOptions>("One", o => o.Instance = new Singleton());
s.Configure<TestOptions>("Two", o => o.Instance = new Singleton()); s.Configure<TestOptions>("Two", o => o.Instance = new Singleton());
}); });
// Add One scheme // Add One scheme
using var server = host.GetTestServer();
var response = await server.CreateClient().GetAsync("http://example.com/add/One"); var response = await server.CreateClient().GetAsync("http://example.com/add/One");
Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var transaction = await server.SendAsync("http://example.com/auth/One"); var transaction = await server.SendAsync("http://example.com/auth/One");
@ -57,7 +59,8 @@ namespace Microsoft.AspNetCore.Authentication
[Fact] [Fact]
public async Task CanAddAndRemoveSchemes() public async Task CanAddAndRemoveSchemes()
{ {
var server = CreateServer(); using var host = await CreateHost();
using var server = host.GetTestServer();
await Assert.ThrowsAsync<InvalidOperationException>(() => server.SendAsync("http://example.com/auth/One")); await Assert.ThrowsAsync<InvalidOperationException>(() => server.SendAsync("http://example.com/auth/One"));
// Add One scheme // Add One scheme
@ -124,9 +127,11 @@ namespace Microsoft.AspNetCore.Authentication
} }
} }
private static TestServer CreateServer(Action<IServiceCollection> configureServices = null) private static async Task<IHost> CreateHost(Action<IServiceCollection> configureServices = null)
{ {
var builder = new WebHostBuilder() var host = new HostBuilder()
.ConfigureWebHost(builder =>
builder.UseTestServer()
.Configure(app => .Configure(app =>
{ {
app.UseAuthentication(); app.UseAuthentication();
@ -163,8 +168,11 @@ namespace Microsoft.AspNetCore.Authentication
{ {
configureServices?.Invoke(services); configureServices?.Invoke(services);
services.AddAuthentication(); services.AddAuthentication();
}); }))
return new TestServer(builder); .Build();
await host.StartAsync();
return host;
} }
} }
} }

View File

@ -9,6 +9,7 @@ using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.TestHost; using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Logging.Abstractions;
using System; using System;
using System.Linq; using System.Linq;
@ -47,7 +48,7 @@ namespace Microsoft.AspNetCore.Authentication.Facebook
[Fact] [Fact]
public async Task ThrowsIfAppIdMissing() public async Task ThrowsIfAppIdMissing()
{ {
var server = CreateServer( using var host = await CreateHost(
app => { }, app => { },
services => services.AddAuthentication().AddFacebook(o => o.SignInScheme = "Whatever"), services => services.AddAuthentication().AddFacebook(o => o.SignInScheme = "Whatever"),
async context => async context =>
@ -55,6 +56,7 @@ namespace Microsoft.AspNetCore.Authentication.Facebook
await Assert.ThrowsAsync<ArgumentException>("AppId", () => context.ChallengeAsync("Facebook")); await Assert.ThrowsAsync<ArgumentException>("AppId", () => context.ChallengeAsync("Facebook"));
return true; return true;
}); });
using var server = host.GetTestServer();
var transaction = await server.SendAsync("http://example.com/challenge"); var transaction = await server.SendAsync("http://example.com/challenge");
Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode);
} }
@ -62,7 +64,7 @@ namespace Microsoft.AspNetCore.Authentication.Facebook
[Fact] [Fact]
public async Task ThrowsIfAppSecretMissing() public async Task ThrowsIfAppSecretMissing()
{ {
var server = CreateServer( using var host = await CreateHost(
app => { }, app => { },
services => services.AddAuthentication().AddFacebook(o => o.AppId = "Whatever"), services => services.AddAuthentication().AddFacebook(o => o.AppId = "Whatever"),
async context => async context =>
@ -70,6 +72,7 @@ namespace Microsoft.AspNetCore.Authentication.Facebook
await Assert.ThrowsAsync<ArgumentException>("AppSecret", () => context.ChallengeAsync("Facebook")); await Assert.ThrowsAsync<ArgumentException>("AppSecret", () => context.ChallengeAsync("Facebook"));
return true; return true;
}); });
using var server = host.GetTestServer();
var transaction = await server.SendAsync("http://example.com/challenge"); var transaction = await server.SendAsync("http://example.com/challenge");
Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode);
} }
@ -77,7 +80,7 @@ namespace Microsoft.AspNetCore.Authentication.Facebook
[Fact] [Fact]
public async Task ChallengeWillTriggerApplyRedirectEvent() public async Task ChallengeWillTriggerApplyRedirectEvent()
{ {
var server = CreateServer( using var host = await CreateHost(
app => app =>
{ {
app.UseAuthentication(); app.UseAuthentication();
@ -105,6 +108,7 @@ namespace Microsoft.AspNetCore.Authentication.Facebook
await context.ChallengeAsync("Facebook"); await context.ChallengeAsync("Facebook");
return true; return true;
}); });
using var server = host.GetTestServer();
var transaction = await server.SendAsync("http://example.com/challenge"); var transaction = await server.SendAsync("http://example.com/challenge");
Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
var query = transaction.Response.Headers.Location.Query; var query = transaction.Response.Headers.Location.Query;
@ -114,7 +118,7 @@ namespace Microsoft.AspNetCore.Authentication.Facebook
[Fact] [Fact]
public async Task ChallengeWillIncludeScopeAsConfigured() public async Task ChallengeWillIncludeScopeAsConfigured()
{ {
var server = CreateServer( using var host = await CreateHost(
app => app.UseAuthentication(), app => app.UseAuthentication(),
services => services =>
{ {
@ -133,6 +137,7 @@ namespace Microsoft.AspNetCore.Authentication.Facebook
return true; return true;
}); });
using var server = host.GetTestServer();
var transaction = await server.SendAsync("http://example.com/challenge"); var transaction = await server.SendAsync("http://example.com/challenge");
var res = transaction.Response; var res = transaction.Response;
@ -143,7 +148,7 @@ namespace Microsoft.AspNetCore.Authentication.Facebook
[Fact] [Fact]
public async Task ChallengeWillIncludeScopeAsOverwritten() public async Task ChallengeWillIncludeScopeAsOverwritten()
{ {
var server = CreateServer( using var host = await CreateHost(
app => app.UseAuthentication(), app => app.UseAuthentication(),
services => services =>
{ {
@ -164,6 +169,7 @@ namespace Microsoft.AspNetCore.Authentication.Facebook
return true; return true;
}); });
using var server = host.GetTestServer();
var transaction = await server.SendAsync("http://example.com/challenge"); var transaction = await server.SendAsync("http://example.com/challenge");
var res = transaction.Response; var res = transaction.Response;
@ -174,7 +180,7 @@ namespace Microsoft.AspNetCore.Authentication.Facebook
[Fact] [Fact]
public async Task ChallengeWillIncludeScopeAsOverwrittenWithBaseAuthenticationProperties() public async Task ChallengeWillIncludeScopeAsOverwrittenWithBaseAuthenticationProperties()
{ {
var server = CreateServer( using var host = await CreateHost(
app => app.UseAuthentication(), app => app.UseAuthentication(),
services => services =>
{ {
@ -195,6 +201,7 @@ namespace Microsoft.AspNetCore.Authentication.Facebook
return true; return true;
}); });
using var server = host.GetTestServer();
var transaction = await server.SendAsync("http://example.com/challenge"); var transaction = await server.SendAsync("http://example.com/challenge");
var res = transaction.Response; var res = transaction.Response;
@ -205,7 +212,7 @@ namespace Microsoft.AspNetCore.Authentication.Facebook
[Fact] [Fact]
public async Task NestedMapWillNotAffectRedirect() public async Task NestedMapWillNotAffectRedirect()
{ {
var server = CreateServer(app => app.Map("/base", map => using var host = await CreateHost(app => app.Map("/base", map =>
{ {
map.UseAuthentication(); map.UseAuthentication();
map.Map("/login", signoutApp => signoutApp.Run(context => context.ChallengeAsync("Facebook", new AuthenticationProperties() { RedirectUri = "/" }))); map.Map("/login", signoutApp => signoutApp.Run(context => context.ChallengeAsync("Facebook", new AuthenticationProperties() { RedirectUri = "/" })));
@ -222,6 +229,7 @@ namespace Microsoft.AspNetCore.Authentication.Facebook
}, },
handler: null); handler: null);
using var server = host.GetTestServer();
var transaction = await server.SendAsync("http://example.com/base/login"); var transaction = await server.SendAsync("http://example.com/base/login");
Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
var location = transaction.Response.Headers.Location.AbsoluteUri; var location = transaction.Response.Headers.Location.AbsoluteUri;
@ -236,7 +244,7 @@ namespace Microsoft.AspNetCore.Authentication.Facebook
[Fact] [Fact]
public async Task MapWillNotAffectRedirect() public async Task MapWillNotAffectRedirect()
{ {
var server = CreateServer( using var host = await CreateHost(
app => app =>
{ {
app.UseAuthentication(); app.UseAuthentication();
@ -254,6 +262,7 @@ namespace Microsoft.AspNetCore.Authentication.Facebook
}); });
}, },
handler: null); handler: null);
using var server = host.GetTestServer();
var transaction = await server.SendAsync("http://example.com/login"); var transaction = await server.SendAsync("http://example.com/login");
Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
var location = transaction.Response.Headers.Location.AbsoluteUri; var location = transaction.Response.Headers.Location.AbsoluteUri;
@ -268,7 +277,7 @@ namespace Microsoft.AspNetCore.Authentication.Facebook
[Fact] [Fact]
public async Task ChallengeWillTriggerRedirection() public async Task ChallengeWillTriggerRedirection()
{ {
var server = CreateServer( using var host = await CreateHost(
app => app.UseAuthentication(), app => app.UseAuthentication(),
services => services =>
{ {
@ -288,6 +297,7 @@ namespace Microsoft.AspNetCore.Authentication.Facebook
await context.ChallengeAsync("Facebook"); await context.ChallengeAsync("Facebook");
return true; return true;
}); });
using var server = host.GetTestServer();
var transaction = await server.SendAsync("http://example.com/challenge"); var transaction = await server.SendAsync("http://example.com/challenge");
Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
var location = transaction.Response.Headers.Location.AbsoluteUri; var location = transaction.Response.Headers.Location.AbsoluteUri;
@ -305,7 +315,7 @@ namespace Microsoft.AspNetCore.Authentication.Facebook
var customUserInfoEndpoint = "https://graph.facebook.com/me?fields=email,timezone,picture"; var customUserInfoEndpoint = "https://graph.facebook.com/me?fields=email,timezone,picture";
var finalUserInfoEndpoint = string.Empty; var finalUserInfoEndpoint = string.Empty;
var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("FacebookTest")); var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("FacebookTest"));
var server = CreateServer( using var host = await CreateHost(
app => app.UseAuthentication(), app => app.UseAuthentication(),
services => services =>
{ {
@ -350,6 +360,7 @@ namespace Microsoft.AspNetCore.Authentication.Facebook
properties.Items.Add(correlationKey, correlationValue); properties.Items.Add(correlationKey, correlationValue);
properties.RedirectUri = "/me"; properties.RedirectUri = "/me";
var state = stateFormat.Protect(properties); var state = stateFormat.Protect(properties);
using var server = host.GetTestServer();
var transaction = await server.SendAsync( var transaction = await server.SendAsync(
"https://example.com/signin-facebook?code=TestCode&state=" + UrlEncoder.Default.Encode(state), "https://example.com/signin-facebook?code=TestCode&state=" + UrlEncoder.Default.Encode(state),
$".AspNetCore.Correlation.Facebook.{correlationValue}=N"); $".AspNetCore.Correlation.Facebook.{correlationValue}=N");
@ -360,9 +371,11 @@ namespace Microsoft.AspNetCore.Authentication.Facebook
Assert.Contains("&access_token=", finalUserInfoEndpoint); Assert.Contains("&access_token=", finalUserInfoEndpoint);
} }
private static TestServer CreateServer(Action<IApplicationBuilder> configure, Action<IServiceCollection> configureServices, Func<HttpContext, Task<bool>> handler) private static async Task<IHost> CreateHost(Action<IApplicationBuilder> configure, Action<IServiceCollection> configureServices, Func<HttpContext, Task<bool>> handler)
{ {
var builder = new WebHostBuilder() var host = new HostBuilder()
.ConfigureWebHost(builder =>
builder.UseTestServer()
.Configure(app => .Configure(app =>
{ {
configure?.Invoke(app); configure?.Invoke(app);
@ -374,8 +387,11 @@ namespace Microsoft.AspNetCore.Authentication.Facebook
} }
}); });
}) })
.ConfigureServices(configureServices); .ConfigureServices(configureServices))
return new TestServer(builder); .Build();
await host.StartAsync();
return host;
} }
} }
} }

View File

@ -8,6 +8,7 @@ using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.TestHost; using Microsoft.AspNetCore.TestHost;
using Microsoft.AspNetCore.WebUtilities; using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Logging.Abstractions;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -48,11 +49,12 @@ namespace Microsoft.AspNetCore.Authentication.Google
[Fact] [Fact]
public async Task ChallengeWillTriggerRedirection() public async Task ChallengeWillTriggerRedirection()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ClientId = "Test Id"; o.ClientId = "Test Id";
o.ClientSecret = "Test Secret"; o.ClientSecret = "Test Secret";
}); });
using var server = host.GetTestServer();
var transaction = await server.SendAsync("https://example.com/challenge"); var transaction = await server.SendAsync("https://example.com/challenge");
Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
var location = transaction.Response.Headers.Location.ToString(); var location = transaction.Response.Headers.Location.ToString();
@ -72,11 +74,12 @@ namespace Microsoft.AspNetCore.Authentication.Google
[Fact] [Fact]
public async Task SignInThrows() public async Task SignInThrows()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ClientId = "Test Id"; o.ClientId = "Test Id";
o.ClientSecret = "Test Secret"; o.ClientSecret = "Test Secret";
}); });
using var server = host.GetTestServer();
var transaction = await server.SendAsync("https://example.com/signIn"); var transaction = await server.SendAsync("https://example.com/signIn");
Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode);
} }
@ -84,11 +87,12 @@ namespace Microsoft.AspNetCore.Authentication.Google
[Fact] [Fact]
public async Task SignOutThrows() public async Task SignOutThrows()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ClientId = "Test Id"; o.ClientId = "Test Id";
o.ClientSecret = "Test Secret"; o.ClientSecret = "Test Secret";
}); });
using var server = host.GetTestServer();
var transaction = await server.SendAsync("https://example.com/signOut"); var transaction = await server.SendAsync("https://example.com/signOut");
Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode);
} }
@ -96,11 +100,12 @@ namespace Microsoft.AspNetCore.Authentication.Google
[Fact] [Fact]
public async Task ForbidThrows() public async Task ForbidThrows()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ClientId = "Test Id"; o.ClientId = "Test Id";
o.ClientSecret = "Test Secret"; o.ClientSecret = "Test Secret";
}); });
using var server = host.GetTestServer();
var transaction = await server.SendAsync("https://example.com/signOut"); var transaction = await server.SendAsync("https://example.com/signOut");
Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode);
} }
@ -108,11 +113,12 @@ namespace Microsoft.AspNetCore.Authentication.Google
[Fact] [Fact]
public async Task Challenge401WillNotTriggerRedirection() public async Task Challenge401WillNotTriggerRedirection()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ClientId = "Test Id"; o.ClientId = "Test Id";
o.ClientSecret = "Test Secret"; o.ClientSecret = "Test Secret";
}); });
using var server = host.GetTestServer();
var transaction = await server.SendAsync("https://example.com/401"); var transaction = await server.SendAsync("https://example.com/401");
Assert.Equal(HttpStatusCode.Unauthorized, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.Unauthorized, transaction.Response.StatusCode);
} }
@ -120,11 +126,12 @@ namespace Microsoft.AspNetCore.Authentication.Google
[Fact] [Fact]
public async Task ChallengeWillSetCorrelationCookie() public async Task ChallengeWillSetCorrelationCookie()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ClientId = "Test Id"; o.ClientId = "Test Id";
o.ClientSecret = "Test Secret"; o.ClientSecret = "Test Secret";
}); });
using var server = host.GetTestServer();
var transaction = await server.SendAsync("https://example.com/challenge"); var transaction = await server.SendAsync("https://example.com/challenge");
Assert.Contains(transaction.SetCookie, cookie => cookie.StartsWith(".AspNetCore.Correlation.Google.")); Assert.Contains(transaction.SetCookie, cookie => cookie.StartsWith(".AspNetCore.Correlation.Google."));
} }
@ -132,11 +139,12 @@ namespace Microsoft.AspNetCore.Authentication.Google
[Fact] [Fact]
public async Task ChallengeWillSetDefaultScope() public async Task ChallengeWillSetDefaultScope()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ClientId = "Test Id"; o.ClientId = "Test Id";
o.ClientSecret = "Test Secret"; o.ClientSecret = "Test Secret";
}); });
using var server = host.GetTestServer();
var transaction = await server.SendAsync("https://example.com/challenge"); var transaction = await server.SendAsync("https://example.com/challenge");
Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
var query = transaction.Response.Headers.Location.Query; var query = transaction.Response.Headers.Location.Query;
@ -147,7 +155,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
public async Task ChallengeWillUseAuthenticationPropertiesParametersAsQueryArguments() public async Task ChallengeWillUseAuthenticationPropertiesParametersAsQueryArguments()
{ {
var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("GoogleTest")); var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("GoogleTest"));
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ClientId = "Test Id"; o.ClientId = "Test Id";
o.ClientSecret = "Test Secret"; o.ClientSecret = "Test Secret";
@ -172,6 +180,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
return Task.FromResult<object>(null); return Task.FromResult<object>(null);
}); });
using var server = host.GetTestServer();
var transaction = await server.SendAsync("https://example.com/challenge2"); var transaction = await server.SendAsync("https://example.com/challenge2");
Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
@ -198,7 +207,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
public async Task ChallengeWillUseAuthenticationPropertiesItemsAsParameters() public async Task ChallengeWillUseAuthenticationPropertiesItemsAsParameters()
{ {
var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("GoogleTest")); var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("GoogleTest"));
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ClientId = "Test Id"; o.ClientId = "Test Id";
o.ClientSecret = "Test Secret"; o.ClientSecret = "Test Secret";
@ -223,6 +232,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
return Task.FromResult<object>(null); return Task.FromResult<object>(null);
}); });
using var server = host.GetTestServer();
var transaction = await server.SendAsync("https://example.com/challenge2"); var transaction = await server.SendAsync("https://example.com/challenge2");
Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
@ -249,7 +259,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
public async Task ChallengeWillUseAuthenticationPropertiesItemsAsQueryArgumentsButParametersWillOverwrite() public async Task ChallengeWillUseAuthenticationPropertiesItemsAsQueryArgumentsButParametersWillOverwrite()
{ {
var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("GoogleTest")); var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("GoogleTest"));
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ClientId = "Test Id"; o.ClientId = "Test Id";
o.ClientSecret = "Test Secret"; o.ClientSecret = "Test Secret";
@ -278,6 +288,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
return Task.FromResult<object>(null); return Task.FromResult<object>(null);
}); });
using var server = host.GetTestServer();
var transaction = await server.SendAsync("https://example.com/challenge2"); var transaction = await server.SendAsync("https://example.com/challenge2");
Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
@ -303,7 +314,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
[Fact] [Fact]
public async Task ChallengeWillTriggerApplyRedirectEvent() public async Task ChallengeWillTriggerApplyRedirectEvent()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ClientId = "Test Id"; o.ClientId = "Test Id";
o.ClientSecret = "Test Secret"; o.ClientSecret = "Test Secret";
@ -316,6 +327,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
} }
}; };
}); });
using var server = host.GetTestServer();
var transaction = await server.SendAsync("https://example.com/challenge"); var transaction = await server.SendAsync("https://example.com/challenge");
Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
var query = transaction.Response.Headers.Location.Query; var query = transaction.Response.Headers.Location.Query;
@ -325,7 +337,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
[Fact] [Fact]
public async Task AuthenticateWithoutCookieWillFail() public async Task AuthenticateWithoutCookieWillFail()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ClientId = "Test Id"; o.ClientId = "Test Id";
o.ClientSecret = "Test Secret"; o.ClientSecret = "Test Secret";
@ -340,6 +352,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
Assert.NotNull(result.Failure); Assert.NotNull(result.Failure);
} }
}); });
using var server = host.GetTestServer();
var transaction = await server.SendAsync("https://example.com/auth"); var transaction = await server.SendAsync("https://example.com/auth");
Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode);
} }
@ -347,11 +360,12 @@ namespace Microsoft.AspNetCore.Authentication.Google
[Fact] [Fact]
public async Task ReplyPathWithoutStateQueryStringWillBeRejected() public async Task ReplyPathWithoutStateQueryStringWillBeRejected()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ClientId = "Test Id"; o.ClientId = "Test Id";
o.ClientSecret = "Test Secret"; o.ClientSecret = "Test Secret";
}); });
using var server = host.GetTestServer();
var error = await Assert.ThrowsAnyAsync<Exception>(() => server.SendAsync("https://example.com/signin-google?code=TestCode")); var error = await Assert.ThrowsAnyAsync<Exception>(() => server.SendAsync("https://example.com/signin-google?code=TestCode"));
Assert.Equal("The oauth state was missing or invalid.", error.GetBaseException().Message); Assert.Equal("The oauth state was missing or invalid.", error.GetBaseException().Message);
} }
@ -361,7 +375,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
[InlineData(false)] [InlineData(false)]
public async Task ReplyPathWithAccessDeniedErrorFails(bool redirect) public async Task ReplyPathWithAccessDeniedErrorFails(bool redirect)
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ClientId = "Test Id"; o.ClientId = "Test Id";
o.ClientSecret = "Test Secret"; o.ClientSecret = "Test Secret";
@ -376,6 +390,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
} }
} : new OAuthEvents(); } : new OAuthEvents();
}); });
using var server = host.GetTestServer();
var sendTask = server.SendAsync("https://example.com/signin-google?error=access_denied&error_description=SoBad&error_uri=foobar&state=protected_state", var sendTask = server.SendAsync("https://example.com/signin-google?error=access_denied&error_description=SoBad&error_uri=foobar&state=protected_state",
".AspNetCore.Correlation.Google.correlationId=N"); ".AspNetCore.Correlation.Google.correlationId=N");
if (redirect) if (redirect)
@ -394,7 +409,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
[Fact] [Fact]
public async Task ReplyPathWithAccessDeniedError_AllowsCustomizingPath() public async Task ReplyPathWithAccessDeniedError_AllowsCustomizingPath()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ClientId = "Test Id"; o.ClientId = "Test Id";
o.ClientSecret = "Test Secret"; o.ClientSecret = "Test Secret";
@ -414,6 +429,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
} }
}; };
}); });
using var server = host.GetTestServer();
var transaction = await server.SendAsync("https://example.com/signin-google?error=access_denied&error_description=SoBad&error_uri=foobar&state=protected_state", var transaction = await server.SendAsync("https://example.com/signin-google?error=access_denied&error_description=SoBad&error_uri=foobar&state=protected_state",
".AspNetCore.Correlation.Google.correlationId=N"); ".AspNetCore.Correlation.Google.correlationId=N");
Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
@ -425,7 +441,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
{ {
var accessDeniedCalled = false; var accessDeniedCalled = false;
var remoteFailureCalled = false; var remoteFailureCalled = false;
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ClientId = "Test Id"; o.ClientId = "Test Id";
o.ClientSecret = "Test Secret"; o.ClientSecret = "Test Secret";
@ -456,6 +472,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
} }
}; };
}); });
using var server = host.GetTestServer();
var transaction = await server.SendAsync("https://example.com/signin-google?error=access_denied&error_description=whyitfailed&error_uri=https://example.com/fail&state=protected_state", var transaction = await server.SendAsync("https://example.com/signin-google?error=access_denied&error_description=whyitfailed&error_uri=https://example.com/fail&state=protected_state",
".AspNetCore.Correlation.Google.correlationId=N"); ".AspNetCore.Correlation.Google.correlationId=N");
Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
@ -469,7 +486,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
[InlineData(false)] [InlineData(false)]
public async Task ReplyPathWithErrorFails(bool redirect) public async Task ReplyPathWithErrorFails(bool redirect)
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ClientId = "Test Id"; o.ClientId = "Test Id";
o.ClientSecret = "Test Secret"; o.ClientSecret = "Test Secret";
@ -491,6 +508,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
} }
} : new OAuthEvents(); } : new OAuthEvents();
}); });
using var server = host.GetTestServer();
var sendTask = server.SendAsync("https://example.com/signin-google?error=itfailed&error_description=whyitfailed&error_uri=https://example.com/fail&state=protected_state", var sendTask = server.SendAsync("https://example.com/signin-google?error=itfailed&error_description=whyitfailed&error_uri=https://example.com/fail&state=protected_state",
".AspNetCore.Correlation.Google.correlationId=N"); ".AspNetCore.Correlation.Google.correlationId=N");
if (redirect) if (redirect)
@ -512,7 +530,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
public async Task ReplyPathWillAuthenticateValidAuthorizeCodeAndState(string claimsIssuer) public async Task ReplyPathWillAuthenticateValidAuthorizeCodeAndState(string claimsIssuer)
{ {
var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("GoogleTest")); var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("GoogleTest"));
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ClientId = "Test Id"; o.ClientId = "Test Id";
o.ClientSecret = "Test Secret"; o.ClientSecret = "Test Secret";
@ -531,6 +549,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
properties.Items.Add(correlationKey, correlationValue); properties.Items.Add(correlationKey, correlationValue);
properties.RedirectUri = "/me"; properties.RedirectUri = "/me";
var state = stateFormat.Protect(properties); var state = stateFormat.Protect(properties);
using var server = host.GetTestServer();
var transaction = await server.SendAsync( var transaction = await server.SendAsync(
"https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.Encode(state), "https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.Encode(state),
$".AspNetCore.Correlation.Google.{correlationValue}=N"); $".AspNetCore.Correlation.Google.{correlationValue}=N");
@ -567,7 +586,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
public async Task ReplyPathWillThrowIfCodeIsInvalid(bool redirect) public async Task ReplyPathWillThrowIfCodeIsInvalid(bool redirect)
{ {
var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("GoogleTest")); var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("GoogleTest"));
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ClientId = "Test Id"; o.ClientId = "Test Id";
o.ClientSecret = "Test Secret"; o.ClientSecret = "Test Secret";
@ -597,6 +616,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
properties.RedirectUri = "/me"; properties.RedirectUri = "/me";
var state = stateFormat.Protect(properties); var state = stateFormat.Protect(properties);
using var server = host.GetTestServer();
var sendTask = server.SendAsync( var sendTask = server.SendAsync(
"https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.Encode(state), "https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.Encode(state),
$".AspNetCore.Correlation.Google.{correlationValue}=N"); $".AspNetCore.Correlation.Google.{correlationValue}=N");
@ -620,7 +640,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
public async Task ReplyPathWillRejectIfAccessTokenIsMissing(bool redirect) public async Task ReplyPathWillRejectIfAccessTokenIsMissing(bool redirect)
{ {
var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("GoogleTest")); var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("GoogleTest"));
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ClientId = "Test Id"; o.ClientId = "Test Id";
o.ClientSecret = "Test Secret"; o.ClientSecret = "Test Secret";
@ -648,6 +668,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
properties.Items.Add(correlationKey, correlationValue); properties.Items.Add(correlationKey, correlationValue);
properties.RedirectUri = "/me"; properties.RedirectUri = "/me";
var state = stateFormat.Protect(properties); var state = stateFormat.Protect(properties);
using var server = host.GetTestServer();
var sendTask = server.SendAsync( var sendTask = server.SendAsync(
"https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.Encode(state), "https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.Encode(state),
$".AspNetCore.Correlation.Google.{correlationValue}=N"); $".AspNetCore.Correlation.Google.{correlationValue}=N");
@ -669,7 +690,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
public async Task AuthenticatedEventCanGetRefreshToken() public async Task AuthenticatedEventCanGetRefreshToken()
{ {
var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("GoogleTest")); var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("GoogleTest"));
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ClientId = "Test Id"; o.ClientId = "Test Id";
o.ClientSecret = "Test Secret"; o.ClientSecret = "Test Secret";
@ -691,6 +712,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
properties.Items.Add(correlationKey, correlationValue); properties.Items.Add(correlationKey, correlationValue);
properties.RedirectUri = "/me"; properties.RedirectUri = "/me";
var state = stateFormat.Protect(properties); var state = stateFormat.Protect(properties);
using var server = host.GetTestServer();
var transaction = await server.SendAsync( var transaction = await server.SendAsync(
"https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.Encode(state), "https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.Encode(state),
$".AspNetCore.Correlation.Google.{correlationValue}=N"); $".AspNetCore.Correlation.Google.{correlationValue}=N");
@ -710,7 +732,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
public async Task NullRedirectUriWillRedirectToSlash() public async Task NullRedirectUriWillRedirectToSlash()
{ {
var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("GoogleTest")); var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("GoogleTest"));
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ClientId = "Test Id"; o.ClientId = "Test Id";
o.ClientSecret = "Test Secret"; o.ClientSecret = "Test Secret";
@ -730,6 +752,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
var correlationValue = "TestCorrelationId"; var correlationValue = "TestCorrelationId";
properties.Items.Add(correlationKey, correlationValue); properties.Items.Add(correlationKey, correlationValue);
var state = stateFormat.Protect(properties); var state = stateFormat.Protect(properties);
using var server = host.GetTestServer();
var transaction = await server.SendAsync( var transaction = await server.SendAsync(
"https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.Encode(state), "https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.Encode(state),
$".AspNetCore.Correlation.Google.{correlationValue}=N"); $".AspNetCore.Correlation.Google.{correlationValue}=N");
@ -744,7 +767,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
public async Task ValidateAuthenticatedContext() public async Task ValidateAuthenticatedContext()
{ {
var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("GoogleTest")); var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("GoogleTest"));
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ClientId = "Test Id"; o.ClientId = "Test Id";
o.ClientSecret = "Test Secret"; o.ClientSecret = "Test Secret";
@ -776,6 +799,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
var state = stateFormat.Protect(properties); var state = stateFormat.Protect(properties);
//Post a message to the Google middleware //Post a message to the Google middleware
using var server = host.GetTestServer();
var transaction = await server.SendAsync( var transaction = await server.SendAsync(
"https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.Encode(state), "https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.Encode(state),
$".AspNetCore.Correlation.Google.{correlationValue}=N"); $".AspNetCore.Correlation.Google.{correlationValue}=N");
@ -787,13 +811,14 @@ namespace Microsoft.AspNetCore.Authentication.Google
[Fact] [Fact]
public async Task NoStateCausesException() public async Task NoStateCausesException()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ClientId = "Test Id"; o.ClientId = "Test Id";
o.ClientSecret = "Test Secret"; o.ClientSecret = "Test Secret";
}); });
//Post a message to the Google middleware //Post a message to the Google middleware
using var server = host.GetTestServer();
var error = await Assert.ThrowsAnyAsync<Exception>(() => server.SendAsync("https://example.com/signin-google?code=TestCode")); var error = await Assert.ThrowsAnyAsync<Exception>(() => server.SendAsync("https://example.com/signin-google?code=TestCode"));
Assert.Equal("The oauth state was missing or invalid.", error.GetBaseException().Message); Assert.Equal("The oauth state was missing or invalid.", error.GetBaseException().Message);
} }
@ -802,7 +827,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
public async Task CanRedirectOnError() public async Task CanRedirectOnError()
{ {
var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("GoogleTest")); var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("GoogleTest"));
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ClientId = "Test Id"; o.ClientId = "Test Id";
o.ClientSecret = "Test Secret"; o.ClientSecret = "Test Secret";
@ -818,6 +843,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
}); });
//Post a message to the Google middleware //Post a message to the Google middleware
using var server = host.GetTestServer();
var transaction = await server.SendAsync( var transaction = await server.SendAsync(
"https://example.com/signin-google?code=TestCode"); "https://example.com/signin-google?code=TestCode");
@ -830,7 +856,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
public async Task AuthenticateAutomaticWhenAlreadySignedInSucceeds() public async Task AuthenticateAutomaticWhenAlreadySignedInSucceeds()
{ {
var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("GoogleTest")); var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("GoogleTest"));
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ClientId = "Test Id"; o.ClientId = "Test Id";
o.ClientSecret = "Test Secret"; o.ClientSecret = "Test Secret";
@ -847,6 +873,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
properties.Items.Add(correlationKey, correlationValue); properties.Items.Add(correlationKey, correlationValue);
properties.RedirectUri = "/me"; properties.RedirectUri = "/me";
var state = stateFormat.Protect(properties); var state = stateFormat.Protect(properties);
using var server = host.GetTestServer();
var transaction = await server.SendAsync( var transaction = await server.SendAsync(
"https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.Encode(state), "https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.Encode(state),
$".AspNetCore.Correlation.Google.{correlationValue}=N"); $".AspNetCore.Correlation.Google.{correlationValue}=N");
@ -873,7 +900,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
public async Task AuthenticateGoogleWhenAlreadySignedInSucceeds() public async Task AuthenticateGoogleWhenAlreadySignedInSucceeds()
{ {
var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("GoogleTest")); var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("GoogleTest"));
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ClientId = "Test Id"; o.ClientId = "Test Id";
o.ClientSecret = "Test Secret"; o.ClientSecret = "Test Secret";
@ -890,6 +917,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
properties.Items.Add(correlationKey, correlationValue); properties.Items.Add(correlationKey, correlationValue);
properties.RedirectUri = "/me"; properties.RedirectUri = "/me";
var state = stateFormat.Protect(properties); var state = stateFormat.Protect(properties);
using var server = host.GetTestServer();
var transaction = await server.SendAsync( var transaction = await server.SendAsync(
"https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.Encode(state), "https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.Encode(state),
$".AspNetCore.Correlation.Google.{correlationValue}=N"); $".AspNetCore.Correlation.Google.{correlationValue}=N");
@ -916,7 +944,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
public async Task AuthenticateFacebookWhenAlreadySignedWithGoogleReturnsNull() public async Task AuthenticateFacebookWhenAlreadySignedWithGoogleReturnsNull()
{ {
var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("GoogleTest")); var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("GoogleTest"));
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ClientId = "Test Id"; o.ClientId = "Test Id";
o.ClientSecret = "Test Secret"; o.ClientSecret = "Test Secret";
@ -933,6 +961,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
properties.Items.Add(correlationKey, correlationValue); properties.Items.Add(correlationKey, correlationValue);
properties.RedirectUri = "/me"; properties.RedirectUri = "/me";
var state = stateFormat.Protect(properties); var state = stateFormat.Protect(properties);
using var server = host.GetTestServer();
var transaction = await server.SendAsync( var transaction = await server.SendAsync(
"https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.Encode(state), "https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.Encode(state),
$".AspNetCore.Correlation.Google.{correlationValue}=N"); $".AspNetCore.Correlation.Google.{correlationValue}=N");
@ -952,7 +981,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
public async Task ChallengeFacebookWhenAlreadySignedWithGoogleSucceeds() public async Task ChallengeFacebookWhenAlreadySignedWithGoogleSucceeds()
{ {
var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("GoogleTest")); var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("GoogleTest"));
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ClientId = "Test Id"; o.ClientId = "Test Id";
o.ClientSecret = "Test Secret"; o.ClientSecret = "Test Secret";
@ -969,6 +998,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
properties.Items.Add(correlationKey, correlationValue); properties.Items.Add(correlationKey, correlationValue);
properties.RedirectUri = "/me"; properties.RedirectUri = "/me";
var state = stateFormat.Protect(properties); var state = stateFormat.Protect(properties);
using var server = host.GetTestServer();
var transaction = await server.SendAsync( var transaction = await server.SendAsync(
"https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.Encode(state), "https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.Encode(state),
$".AspNetCore.Correlation.Google.{correlationValue}=N"); $".AspNetCore.Correlation.Google.{correlationValue}=N");
@ -1040,9 +1070,11 @@ namespace Microsoft.AspNetCore.Authentication.Google
} }
} }
private static TestServer CreateServer(Action<GoogleOptions> configureOptions, Func<HttpContext, Task> testpath = null) private static async Task<IHost> CreateHost(Action<GoogleOptions> configureOptions, Func<HttpContext, Task> testpath = null)
{ {
var builder = new WebHostBuilder() var host = new HostBuilder()
.ConfigureWebHost(builder =>
builder.UseTestServer()
.Configure(app => .Configure(app =>
{ {
app.UseAuthentication(); app.UseAuthentication();
@ -1131,8 +1163,11 @@ namespace Microsoft.AspNetCore.Authentication.Google
o.ClientId = "Test ClientId"; o.ClientId = "Test ClientId";
o.ClientSecret = "Test AppSecrent"; o.ClientSecret = "Test AppSecrent";
}); });
}); }))
return new TestServer(builder); .Build();
await host.StartAsync();
return host;
} }
private class TestStateDataFormat : ISecureDataFormat<AuthenticationProperties> private class TestStateDataFormat : ISecureDataFormat<AuthenticationProperties>

View File

@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.TestHost; using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.IdentityModel.Tokens; using Microsoft.IdentityModel.Tokens;
using System; using System;
using System.IdentityModel.Tokens.Jwt; using System.IdentityModel.Tokens.Jwt;
@ -61,7 +62,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
var tokenText = new JwtSecurityTokenHandler().WriteToken(token); var tokenText = new JwtSecurityTokenHandler().WriteToken(token);
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.TokenValidationParameters = new TokenValidationParameters() o.TokenValidationParameters = new TokenValidationParameters()
{ {
@ -72,6 +73,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
}); });
var newBearerToken = "Bearer " + tokenText; var newBearerToken = "Bearer " + tokenText;
using var server = host.GetTestServer();
var response = await SendAsync(server, "http://example.com/oauth", newBearerToken); var response = await SendAsync(server, "http://example.com/oauth", newBearerToken);
Assert.Equal(HttpStatusCode.OK, response.Response.StatusCode); Assert.Equal(HttpStatusCode.OK, response.Response.StatusCode);
} }
@ -96,7 +98,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
var tokenText = new JwtSecurityTokenHandler().WriteToken(token); var tokenText = new JwtSecurityTokenHandler().WriteToken(token);
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.SaveToken = true; o.SaveToken = true;
o.TokenValidationParameters = new TokenValidationParameters() o.TokenValidationParameters = new TokenValidationParameters()
@ -108,6 +110,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
}); });
var newBearerToken = "Bearer " + tokenText; var newBearerToken = "Bearer " + tokenText;
using var server = host.GetTestServer();
var response = await SendAsync(server, "http://example.com/token", newBearerToken); var response = await SendAsync(server, "http://example.com/token", newBearerToken);
Assert.Equal(HttpStatusCode.OK, response.Response.StatusCode); Assert.Equal(HttpStatusCode.OK, response.Response.StatusCode);
Assert.Equal(tokenText, await response.Response.Content.ReadAsStringAsync()); Assert.Equal(tokenText, await response.Response.Content.ReadAsStringAsync());
@ -116,7 +119,8 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
[Fact] [Fact]
public async Task SignInThrows() public async Task SignInThrows()
{ {
var server = CreateServer(); using var host = await CreateHost();
using var server = host.GetTestServer();
var transaction = await server.SendAsync("https://example.com/signIn"); var transaction = await server.SendAsync("https://example.com/signIn");
Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode);
} }
@ -124,7 +128,8 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
[Fact] [Fact]
public async Task SignOutThrows() public async Task SignOutThrows()
{ {
var server = CreateServer(); using var host = await CreateHost();
using var server = host.GetTestServer();
var transaction = await server.SendAsync("https://example.com/signOut"); var transaction = await server.SendAsync("https://example.com/signOut");
Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode);
} }
@ -132,7 +137,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
[Fact] [Fact]
public async Task ThrowAtAuthenticationFailedEvent() public async Task ThrowAtAuthenticationFailedEvent()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.Events = new JwtBearerEvents o.Events = new JwtBearerEvents
{ {
@ -164,6 +169,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
} }
}); });
using var server = host.GetTestServer();
var transaction = await server.SendAsync("https://example.com/signIn"); var transaction = await server.SendAsync("https://example.com/signIn");
Assert.Equal(HttpStatusCode.Unauthorized, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.Unauthorized, transaction.Response.StatusCode);
@ -172,7 +178,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
[Fact] [Fact]
public async Task CustomHeaderReceived() public async Task CustomHeaderReceived()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.Events = new JwtBearerEvents() o.Events = new JwtBearerEvents()
{ {
@ -193,6 +199,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
}; };
}); });
using var server = host.GetTestServer();
var response = await SendAsync(server, "http://example.com/oauth", "someHeader someblob"); var response = await SendAsync(server, "http://example.com/oauth", "someHeader someblob");
Assert.Equal(HttpStatusCode.OK, response.Response.StatusCode); Assert.Equal(HttpStatusCode.OK, response.Response.StatusCode);
Assert.Equal("Bob le Magnifique", response.ResponseText); Assert.Equal("Bob le Magnifique", response.ResponseText);
@ -201,7 +208,8 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
[Fact] [Fact]
public async Task NoHeaderReceived() public async Task NoHeaderReceived()
{ {
var server = CreateServer(); using var host = await CreateHost();
using var server = host.GetTestServer();
var response = await SendAsync(server, "http://example.com/oauth"); var response = await SendAsync(server, "http://example.com/oauth");
Assert.Equal(HttpStatusCode.Unauthorized, response.Response.StatusCode); Assert.Equal(HttpStatusCode.Unauthorized, response.Response.StatusCode);
} }
@ -209,7 +217,8 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
[Fact] [Fact]
public async Task HeaderWithoutBearerReceived() public async Task HeaderWithoutBearerReceived()
{ {
var server = CreateServer(); using var host = await CreateHost();
using var server = host.GetTestServer();
var response = await SendAsync(server, "http://example.com/oauth", "Token"); var response = await SendAsync(server, "http://example.com/oauth", "Token");
Assert.Equal(HttpStatusCode.Unauthorized, response.Response.StatusCode); Assert.Equal(HttpStatusCode.Unauthorized, response.Response.StatusCode);
} }
@ -217,7 +226,8 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
[Fact] [Fact]
public async Task UnrecognizedTokenReceived() public async Task UnrecognizedTokenReceived()
{ {
var server = CreateServer(); using var host = await CreateHost();
using var server = host.GetTestServer();
var response = await SendAsync(server, "http://example.com/oauth", "Bearer someblob"); var response = await SendAsync(server, "http://example.com/oauth", "Bearer someblob");
Assert.Equal(HttpStatusCode.Unauthorized, response.Response.StatusCode); Assert.Equal(HttpStatusCode.Unauthorized, response.Response.StatusCode);
Assert.Equal("", response.ResponseText); Assert.Equal("", response.ResponseText);
@ -226,12 +236,13 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
[Fact] [Fact]
public async Task InvalidTokenReceived() public async Task InvalidTokenReceived()
{ {
var server = CreateServer(options => using var host = await CreateHost(options =>
{ {
options.SecurityTokenValidators.Clear(); options.SecurityTokenValidators.Clear();
options.SecurityTokenValidators.Add(new InvalidTokenValidator()); options.SecurityTokenValidators.Add(new InvalidTokenValidator());
}); });
using var server = host.GetTestServer();
var response = await SendAsync(server, "http://example.com/oauth", "Bearer someblob"); var response = await SendAsync(server, "http://example.com/oauth", "Bearer someblob");
Assert.Equal(HttpStatusCode.Unauthorized, response.Response.StatusCode); Assert.Equal(HttpStatusCode.Unauthorized, response.Response.StatusCode);
Assert.Equal("Bearer error=\"invalid_token\"", response.Response.Headers.WwwAuthenticate.First().ToString()); Assert.Equal("Bearer error=\"invalid_token\"", response.Response.Headers.WwwAuthenticate.First().ToString());
@ -249,12 +260,13 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
[InlineData(typeof(SecurityTokenSignatureKeyNotFoundException), "The signature key was not found")] [InlineData(typeof(SecurityTokenSignatureKeyNotFoundException), "The signature key was not found")]
public async Task ExceptionReportedInHeaderForAuthenticationFailures(Type errorType, string message) public async Task ExceptionReportedInHeaderForAuthenticationFailures(Type errorType, string message)
{ {
var server = CreateServer(options => using var host = await CreateHost(options =>
{ {
options.SecurityTokenValidators.Clear(); options.SecurityTokenValidators.Clear();
options.SecurityTokenValidators.Add(new InvalidTokenValidator(errorType)); options.SecurityTokenValidators.Add(new InvalidTokenValidator(errorType));
}); });
using var server = host.GetTestServer();
var response = await SendAsync(server, "http://example.com/oauth", "Bearer someblob"); var response = await SendAsync(server, "http://example.com/oauth", "Bearer someblob");
Assert.Equal(HttpStatusCode.Unauthorized, response.Response.StatusCode); Assert.Equal(HttpStatusCode.Unauthorized, response.Response.StatusCode);
Assert.Equal($"Bearer error=\"invalid_token\", error_description=\"{message}\"", response.Response.Headers.WwwAuthenticate.First().ToString()); Assert.Equal($"Bearer error=\"invalid_token\", error_description=\"{message}\"", response.Response.Headers.WwwAuthenticate.First().ToString());
@ -269,12 +281,13 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
[InlineData(typeof(SecurityTokenExpiredException), "The token expired at '02/20/2000 00:00:00'")] [InlineData(typeof(SecurityTokenExpiredException), "The token expired at '02/20/2000 00:00:00'")]
public async Task ExceptionReportedInHeaderWithDetailsForAuthenticationFailures(Type errorType, string message) public async Task ExceptionReportedInHeaderWithDetailsForAuthenticationFailures(Type errorType, string message)
{ {
var server = CreateServer(options => using var host = await CreateHost(options =>
{ {
options.SecurityTokenValidators.Clear(); options.SecurityTokenValidators.Clear();
options.SecurityTokenValidators.Add(new DetailedInvalidTokenValidator(errorType)); options.SecurityTokenValidators.Add(new DetailedInvalidTokenValidator(errorType));
}); });
using var server = host.GetTestServer();
var response = await SendAsync(server, "http://example.com/oauth", "Bearer someblob"); var response = await SendAsync(server, "http://example.com/oauth", "Bearer someblob");
Assert.Equal(HttpStatusCode.Unauthorized, response.Response.StatusCode); Assert.Equal(HttpStatusCode.Unauthorized, response.Response.StatusCode);
Assert.Equal($"Bearer error=\"invalid_token\", error_description=\"{message}\"", response.Response.Headers.WwwAuthenticate.First().ToString()); Assert.Equal($"Bearer error=\"invalid_token\", error_description=\"{message}\"", response.Response.Headers.WwwAuthenticate.First().ToString());
@ -285,12 +298,13 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
[InlineData(typeof(ArgumentException))] [InlineData(typeof(ArgumentException))]
public async Task ExceptionNotReportedInHeaderForOtherFailures(Type errorType) public async Task ExceptionNotReportedInHeaderForOtherFailures(Type errorType)
{ {
var server = CreateServer(options => using var host = await CreateHost(options =>
{ {
options.SecurityTokenValidators.Clear(); options.SecurityTokenValidators.Clear();
options.SecurityTokenValidators.Add(new InvalidTokenValidator(errorType)); options.SecurityTokenValidators.Add(new InvalidTokenValidator(errorType));
}); });
using var server = host.GetTestServer();
var response = await SendAsync(server, "http://example.com/oauth", "Bearer someblob"); var response = await SendAsync(server, "http://example.com/oauth", "Bearer someblob");
Assert.Equal(HttpStatusCode.Unauthorized, response.Response.StatusCode); Assert.Equal(HttpStatusCode.Unauthorized, response.Response.StatusCode);
Assert.Equal("Bearer error=\"invalid_token\"", response.Response.Headers.WwwAuthenticate.First().ToString()); Assert.Equal("Bearer error=\"invalid_token\"", response.Response.Headers.WwwAuthenticate.First().ToString());
@ -300,13 +314,14 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
[Fact] [Fact]
public async Task ExceptionsReportedInHeaderForMultipleAuthenticationFailures() public async Task ExceptionsReportedInHeaderForMultipleAuthenticationFailures()
{ {
var server = CreateServer(options => using var host = await CreateHost(options =>
{ {
options.SecurityTokenValidators.Clear(); options.SecurityTokenValidators.Clear();
options.SecurityTokenValidators.Add(new InvalidTokenValidator(typeof(SecurityTokenInvalidAudienceException))); options.SecurityTokenValidators.Add(new InvalidTokenValidator(typeof(SecurityTokenInvalidAudienceException)));
options.SecurityTokenValidators.Add(new InvalidTokenValidator(typeof(SecurityTokenSignatureKeyNotFoundException))); options.SecurityTokenValidators.Add(new InvalidTokenValidator(typeof(SecurityTokenSignatureKeyNotFoundException)));
}); });
using var server = host.GetTestServer();
var response = await SendAsync(server, "http://example.com/oauth", "Bearer someblob"); var response = await SendAsync(server, "http://example.com/oauth", "Bearer someblob");
Assert.Equal(HttpStatusCode.Unauthorized, response.Response.StatusCode); Assert.Equal(HttpStatusCode.Unauthorized, response.Response.StatusCode);
Assert.Equal("Bearer error=\"invalid_token\", error_description=\"The audience '(null)' is invalid; The signature key was not found\"", Assert.Equal("Bearer error=\"invalid_token\", error_description=\"The audience '(null)' is invalid; The signature key was not found\"",
@ -323,7 +338,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
[InlineData(null, null, "custom_uri")] [InlineData(null, null, "custom_uri")]
public async Task ExceptionsReportedInHeaderExposesUserDefinedError(string error, string description, string uri) public async Task ExceptionsReportedInHeaderExposesUserDefinedError(string error, string description, string uri)
{ {
var server = CreateServer(options => using var host = await CreateHost(options =>
{ {
options.Events = new JwtBearerEvents options.Events = new JwtBearerEvents
{ {
@ -338,6 +353,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
}; };
}); });
using var server = host.GetTestServer();
var response = await SendAsync(server, "http://example.com/oauth", "Bearer someblob"); var response = await SendAsync(server, "http://example.com/oauth", "Bearer someblob");
Assert.Equal(HttpStatusCode.Unauthorized, response.Response.StatusCode); Assert.Equal(HttpStatusCode.Unauthorized, response.Response.StatusCode);
Assert.Equal("", response.ResponseText); Assert.Equal("", response.ResponseText);
@ -380,11 +396,12 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
[Fact] [Fact]
public async Task ExceptionNotReportedInHeaderWhenIncludeErrorDetailsIsFalse() public async Task ExceptionNotReportedInHeaderWhenIncludeErrorDetailsIsFalse()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.IncludeErrorDetails = false; o.IncludeErrorDetails = false;
}); });
using var server = host.GetTestServer();
var response = await SendAsync(server, "http://example.com/oauth", "Bearer someblob"); var response = await SendAsync(server, "http://example.com/oauth", "Bearer someblob");
Assert.Equal(HttpStatusCode.Unauthorized, response.Response.StatusCode); Assert.Equal(HttpStatusCode.Unauthorized, response.Response.StatusCode);
Assert.Equal("Bearer", response.Response.Headers.WwwAuthenticate.First().ToString()); Assert.Equal("Bearer", response.Response.Headers.WwwAuthenticate.First().ToString());
@ -394,8 +411,9 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
[Fact] [Fact]
public async Task ExceptionNotReportedInHeaderWhenTokenWasMissing() public async Task ExceptionNotReportedInHeaderWhenTokenWasMissing()
{ {
var server = CreateServer(); using var host = await CreateHost();
using var server = host.GetTestServer();
var response = await SendAsync(server, "http://example.com/oauth"); var response = await SendAsync(server, "http://example.com/oauth");
Assert.Equal(HttpStatusCode.Unauthorized, response.Response.StatusCode); Assert.Equal(HttpStatusCode.Unauthorized, response.Response.StatusCode);
Assert.Equal("Bearer", response.Response.Headers.WwwAuthenticate.First().ToString()); Assert.Equal("Bearer", response.Response.Headers.WwwAuthenticate.First().ToString());
@ -405,7 +423,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
[Fact] [Fact]
public async Task CustomTokenValidated() public async Task CustomTokenValidated()
{ {
var server = CreateServer(options => using var host = await CreateHost(options =>
{ {
options.Events = new JwtBearerEvents() options.Events = new JwtBearerEvents()
{ {
@ -432,6 +450,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
options.SecurityTokenValidators.Add(new BlobTokenValidator(JwtBearerDefaults.AuthenticationScheme)); options.SecurityTokenValidators.Add(new BlobTokenValidator(JwtBearerDefaults.AuthenticationScheme));
}); });
using var server = host.GetTestServer();
var response = await SendAsync(server, "http://example.com/oauth", "Bearer someblob"); var response = await SendAsync(server, "http://example.com/oauth", "Bearer someblob");
Assert.Equal(HttpStatusCode.OK, response.Response.StatusCode); Assert.Equal(HttpStatusCode.OK, response.Response.StatusCode);
Assert.Equal("Bob le Magnifique", response.ResponseText); Assert.Equal("Bob le Magnifique", response.ResponseText);
@ -440,7 +459,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
[Fact] [Fact]
public async Task RetrievingTokenFromAlternateLocation() public async Task RetrievingTokenFromAlternateLocation()
{ {
var server = CreateServer(options => using var host = await CreateHost(options =>
{ {
options.Events = new JwtBearerEvents() options.Events = new JwtBearerEvents()
{ {
@ -457,6 +476,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
})); }));
}); });
using var server = host.GetTestServer();
var response = await SendAsync(server, "http://example.com/oauth", "Bearer Token"); var response = await SendAsync(server, "http://example.com/oauth", "Bearer Token");
Assert.Equal(HttpStatusCode.OK, response.Response.StatusCode); Assert.Equal(HttpStatusCode.OK, response.Response.StatusCode);
Assert.Equal("Bob le Tout Puissant", response.ResponseText); Assert.Equal("Bob le Tout Puissant", response.ResponseText);
@ -465,7 +485,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
[Fact] [Fact]
public async Task EventOnMessageReceivedSkip_NoMoreEventsExecuted() public async Task EventOnMessageReceivedSkip_NoMoreEventsExecuted()
{ {
var server = CreateServer(options => using var host = await CreateHost(options =>
{ {
options.Events = new JwtBearerEvents() options.Events = new JwtBearerEvents()
{ {
@ -489,6 +509,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
}; };
}); });
using var server = host.GetTestServer();
var response = await SendAsync(server, "http://example.com/checkforerrors", "Bearer Token"); var response = await SendAsync(server, "http://example.com/checkforerrors", "Bearer Token");
Assert.Equal(HttpStatusCode.OK, response.Response.StatusCode); Assert.Equal(HttpStatusCode.OK, response.Response.StatusCode);
Assert.Equal(string.Empty, response.ResponseText); Assert.Equal(string.Empty, response.ResponseText);
@ -497,7 +518,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
[Fact] [Fact]
public async Task EventOnMessageReceivedReject_NoMoreEventsExecuted() public async Task EventOnMessageReceivedReject_NoMoreEventsExecuted()
{ {
var server = CreateServer(options => using var host = await CreateHost(options =>
{ {
options.Events = new JwtBearerEvents() options.Events = new JwtBearerEvents()
{ {
@ -522,6 +543,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
}; };
}); });
using var server = host.GetTestServer();
var exception = await Assert.ThrowsAsync<Exception>(delegate var exception = await Assert.ThrowsAsync<Exception>(delegate
{ {
return SendAsync(server, "http://example.com/checkforerrors", "Bearer Token"); return SendAsync(server, "http://example.com/checkforerrors", "Bearer Token");
@ -533,7 +555,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
[Fact] [Fact]
public async Task EventOnTokenValidatedSkip_NoMoreEventsExecuted() public async Task EventOnTokenValidatedSkip_NoMoreEventsExecuted()
{ {
var server = CreateServer(options => using var host = await CreateHost(options =>
{ {
options.Events = new JwtBearerEvents() options.Events = new JwtBearerEvents()
{ {
@ -555,6 +577,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
options.SecurityTokenValidators.Add(new BlobTokenValidator("JWT")); options.SecurityTokenValidators.Add(new BlobTokenValidator("JWT"));
}); });
using var server = host.GetTestServer();
var response = await SendAsync(server, "http://example.com/checkforerrors", "Bearer Token"); var response = await SendAsync(server, "http://example.com/checkforerrors", "Bearer Token");
Assert.Equal(HttpStatusCode.OK, response.Response.StatusCode); Assert.Equal(HttpStatusCode.OK, response.Response.StatusCode);
Assert.Equal(string.Empty, response.ResponseText); Assert.Equal(string.Empty, response.ResponseText);
@ -563,7 +586,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
[Fact] [Fact]
public async Task EventOnTokenValidatedReject_NoMoreEventsExecuted() public async Task EventOnTokenValidatedReject_NoMoreEventsExecuted()
{ {
var server = CreateServer(options => using var host = await CreateHost(options =>
{ {
options.Events = new JwtBearerEvents() options.Events = new JwtBearerEvents()
{ {
@ -586,6 +609,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
options.SecurityTokenValidators.Add(new BlobTokenValidator("JWT")); options.SecurityTokenValidators.Add(new BlobTokenValidator("JWT"));
}); });
using var server = host.GetTestServer();
var exception = await Assert.ThrowsAsync<Exception>(delegate var exception = await Assert.ThrowsAsync<Exception>(delegate
{ {
return SendAsync(server, "http://example.com/checkforerrors", "Bearer Token"); return SendAsync(server, "http://example.com/checkforerrors", "Bearer Token");
@ -597,7 +621,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
[Fact] [Fact]
public async Task EventOnAuthenticationFailedSkip_NoMoreEventsExecuted() public async Task EventOnAuthenticationFailedSkip_NoMoreEventsExecuted()
{ {
var server = CreateServer(options => using var host = await CreateHost(options =>
{ {
options.Events = new JwtBearerEvents() options.Events = new JwtBearerEvents()
{ {
@ -619,6 +643,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
options.SecurityTokenValidators.Add(new BlobTokenValidator("JWT")); options.SecurityTokenValidators.Add(new BlobTokenValidator("JWT"));
}); });
using var server = host.GetTestServer();
var response = await SendAsync(server, "http://example.com/checkforerrors", "Bearer Token"); var response = await SendAsync(server, "http://example.com/checkforerrors", "Bearer Token");
Assert.Equal(HttpStatusCode.OK, response.Response.StatusCode); Assert.Equal(HttpStatusCode.OK, response.Response.StatusCode);
Assert.Equal(string.Empty, response.ResponseText); Assert.Equal(string.Empty, response.ResponseText);
@ -627,7 +652,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
[Fact] [Fact]
public async Task EventOnAuthenticationFailedReject_NoMoreEventsExecuted() public async Task EventOnAuthenticationFailedReject_NoMoreEventsExecuted()
{ {
var server = CreateServer(options => using var host = await CreateHost(options =>
{ {
options.Events = new JwtBearerEvents() options.Events = new JwtBearerEvents()
{ {
@ -650,6 +675,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
options.SecurityTokenValidators.Add(new BlobTokenValidator("JWT")); options.SecurityTokenValidators.Add(new BlobTokenValidator("JWT"));
}); });
using var server = host.GetTestServer();
var exception = await Assert.ThrowsAsync<Exception>(delegate var exception = await Assert.ThrowsAsync<Exception>(delegate
{ {
return SendAsync(server, "http://example.com/checkforerrors", "Bearer Token"); return SendAsync(server, "http://example.com/checkforerrors", "Bearer Token");
@ -661,7 +687,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
[Fact] [Fact]
public async Task EventOnChallengeSkip_ResponseNotModified() public async Task EventOnChallengeSkip_ResponseNotModified()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.Events = new JwtBearerEvents() o.Events = new JwtBearerEvents()
{ {
@ -673,6 +699,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
}; };
}); });
using var server = host.GetTestServer();
var response = await SendAsync(server, "http://example.com/unauthorized", "Bearer Token"); var response = await SendAsync(server, "http://example.com/unauthorized", "Bearer Token");
Assert.Equal(HttpStatusCode.OK, response.Response.StatusCode); Assert.Equal(HttpStatusCode.OK, response.Response.StatusCode);
Assert.Empty(response.Response.Headers.WwwAuthenticate); Assert.Empty(response.Response.Headers.WwwAuthenticate);
@ -684,7 +711,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
{ {
var tokenData = CreateStandardTokenAndKey(); var tokenData = CreateStandardTokenAndKey();
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.TokenValidationParameters = new TokenValidationParameters() o.TokenValidationParameters = new TokenValidationParameters()
{ {
@ -694,6 +721,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
}; };
}); });
var newBearerToken = "Bearer " + tokenData.tokenText; var newBearerToken = "Bearer " + tokenData.tokenText;
using var server = host.GetTestServer();
var response = await SendAsync(server, "http://example.com/forbidden", newBearerToken); var response = await SendAsync(server, "http://example.com/forbidden", newBearerToken);
Assert.Equal(HttpStatusCode.Forbidden, response.Response.StatusCode); Assert.Equal(HttpStatusCode.Forbidden, response.Response.StatusCode);
} }
@ -702,7 +730,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
public async Task EventOnForbiddenSkip_ResponseNotModified() public async Task EventOnForbiddenSkip_ResponseNotModified()
{ {
var tokenData = CreateStandardTokenAndKey(); var tokenData = CreateStandardTokenAndKey();
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.TokenValidationParameters = new TokenValidationParameters() o.TokenValidationParameters = new TokenValidationParameters()
{ {
@ -719,6 +747,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
}; };
}); });
var newBearerToken = "Bearer " + tokenData.tokenText; var newBearerToken = "Bearer " + tokenData.tokenText;
using var server = host.GetTestServer();
var response = await SendAsync(server, "http://example.com/forbidden", newBearerToken); var response = await SendAsync(server, "http://example.com/forbidden", newBearerToken);
Assert.Equal(HttpStatusCode.Forbidden, response.Response.StatusCode); Assert.Equal(HttpStatusCode.Forbidden, response.Response.StatusCode);
} }
@ -727,7 +756,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
public async Task EventOnForbidden_ResponseModified() public async Task EventOnForbidden_ResponseModified()
{ {
var tokenData = CreateStandardTokenAndKey(); var tokenData = CreateStandardTokenAndKey();
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.TokenValidationParameters = new TokenValidationParameters() o.TokenValidationParameters = new TokenValidationParameters()
{ {
@ -745,6 +774,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
}; };
}); });
var newBearerToken = "Bearer " + tokenData.tokenText; var newBearerToken = "Bearer " + tokenData.tokenText;
using var server = host.GetTestServer();
var response = await SendAsync(server, "http://example.com/forbidden", newBearerToken); var response = await SendAsync(server, "http://example.com/forbidden", newBearerToken);
Assert.Equal(418, (int)response.Response.StatusCode); Assert.Equal(418, (int)response.Response.StatusCode);
Assert.Equal("You Shall Not Pass", await response.Response.Content.ReadAsStringAsync()); Assert.Equal("You Shall Not Pass", await response.Response.Content.ReadAsStringAsync());
@ -896,9 +926,11 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
} }
} }
private static TestServer CreateServer(Action<JwtBearerOptions> options = null, Func<HttpContext, Func<Task>, Task> handlerBeforeAuth = null) private static async Task<IHost> CreateHost(Action<JwtBearerOptions> options = null, Func<HttpContext, Func<Task>, Task> handlerBeforeAuth = null)
{ {
var builder = new WebHostBuilder() var host = new HostBuilder()
.ConfigureWebHost(builder =>
builder.UseTestServer()
.Configure(app => .Configure(app =>
{ {
if (handlerBeforeAuth != null) if (handlerBeforeAuth != null)
@ -969,9 +1001,11 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
} }
}); });
}) })
.ConfigureServices(services => services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options)); .ConfigureServices(services => services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options)))
.Build();
return new TestServer(builder); await host.StartAsync();
return host;
} }
// TODO: see if we can share the TestExtensions SendAsync method (only diff is auth header) // TODO: see if we can share the TestExtensions SendAsync method (only diff is auth header)

View File

@ -9,6 +9,7 @@ using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.TestHost; using Microsoft.AspNetCore.TestHost;
using Microsoft.AspNetCore.WebUtilities; using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Logging.Abstractions;
using System; using System;
using System.Linq; using System.Linq;
@ -48,7 +49,7 @@ namespace Microsoft.AspNetCore.Authentication.Tests.MicrosoftAccount
[Fact] [Fact]
public async Task ChallengeWillTriggerApplyRedirectEvent() public async Task ChallengeWillTriggerApplyRedirectEvent()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ClientId = "Test Client Id"; o.ClientId = "Test Client Id";
o.ClientSecret = "Test Client Secret"; o.ClientSecret = "Test Client Secret";
@ -61,6 +62,8 @@ namespace Microsoft.AspNetCore.Authentication.Tests.MicrosoftAccount
} }
}; };
}); });
using var server = host.GetTestServer();
var transaction = await server.SendAsync("http://example.com/challenge"); var transaction = await server.SendAsync("http://example.com/challenge");
Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
var query = transaction.Response.Headers.Location.Query; var query = transaction.Response.Headers.Location.Query;
@ -70,11 +73,12 @@ namespace Microsoft.AspNetCore.Authentication.Tests.MicrosoftAccount
[Fact] [Fact]
public async Task SignInThrows() public async Task SignInThrows()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ClientId = "Test Id"; o.ClientId = "Test Id";
o.ClientSecret = "Test Secret"; o.ClientSecret = "Test Secret";
}); });
using var server = host.GetTestServer();
var transaction = await server.SendAsync("https://example.com/signIn"); var transaction = await server.SendAsync("https://example.com/signIn");
Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode);
} }
@ -82,11 +86,12 @@ namespace Microsoft.AspNetCore.Authentication.Tests.MicrosoftAccount
[Fact] [Fact]
public async Task SignOutThrows() public async Task SignOutThrows()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ClientId = "Test Id"; o.ClientId = "Test Id";
o.ClientSecret = "Test Secret"; o.ClientSecret = "Test Secret";
}); });
using var server = host.GetTestServer();
var transaction = await server.SendAsync("https://example.com/signOut"); var transaction = await server.SendAsync("https://example.com/signOut");
Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode);
} }
@ -94,11 +99,12 @@ namespace Microsoft.AspNetCore.Authentication.Tests.MicrosoftAccount
[Fact] [Fact]
public async Task ForbidThrows() public async Task ForbidThrows()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ClientId = "Test Id"; o.ClientId = "Test Id";
o.ClientSecret = "Test Secret"; o.ClientSecret = "Test Secret";
}); });
using var server = host.GetTestServer();
var transaction = await server.SendAsync("https://example.com/signOut"); var transaction = await server.SendAsync("https://example.com/signOut");
Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode);
} }
@ -106,11 +112,12 @@ namespace Microsoft.AspNetCore.Authentication.Tests.MicrosoftAccount
[Fact] [Fact]
public async Task ChallengeWillTriggerRedirection() public async Task ChallengeWillTriggerRedirection()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ClientId = "Test Id"; o.ClientId = "Test Id";
o.ClientSecret = "Test Secret"; o.ClientSecret = "Test Secret";
}); });
using var server = host.GetTestServer();
var transaction = await server.SendAsync("http://example.com/challenge"); var transaction = await server.SendAsync("http://example.com/challenge");
Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
var location = transaction.Response.Headers.Location.AbsoluteUri; var location = transaction.Response.Headers.Location.AbsoluteUri;
@ -127,7 +134,7 @@ namespace Microsoft.AspNetCore.Authentication.Tests.MicrosoftAccount
[Fact] [Fact]
public async Task ChallengeWillIncludeScopeAsConfigured() public async Task ChallengeWillIncludeScopeAsConfigured()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ClientId = "Test Id"; o.ClientId = "Test Id";
o.ClientSecret = "Test Secret"; o.ClientSecret = "Test Secret";
@ -135,6 +142,7 @@ namespace Microsoft.AspNetCore.Authentication.Tests.MicrosoftAccount
o.Scope.Add("foo"); o.Scope.Add("foo");
o.Scope.Add("bar"); o.Scope.Add("bar");
}); });
using var server = host.GetTestServer();
var transaction = await server.SendAsync("http://example.com/challenge"); var transaction = await server.SendAsync("http://example.com/challenge");
var res = transaction.Response; var res = transaction.Response;
Assert.Equal(HttpStatusCode.Redirect, res.StatusCode); Assert.Equal(HttpStatusCode.Redirect, res.StatusCode);
@ -144,7 +152,7 @@ namespace Microsoft.AspNetCore.Authentication.Tests.MicrosoftAccount
[Fact] [Fact]
public async Task ChallengeWillIncludeScopeAsOverwritten() public async Task ChallengeWillIncludeScopeAsOverwritten()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ClientId = "Test Id"; o.ClientId = "Test Id";
o.ClientSecret = "Test Secret"; o.ClientSecret = "Test Secret";
@ -152,6 +160,7 @@ namespace Microsoft.AspNetCore.Authentication.Tests.MicrosoftAccount
o.Scope.Add("foo"); o.Scope.Add("foo");
o.Scope.Add("bar"); o.Scope.Add("bar");
}); });
using var server = host.GetTestServer();
var transaction = await server.SendAsync("http://example.com/challengeWithOtherScope"); var transaction = await server.SendAsync("http://example.com/challengeWithOtherScope");
var res = transaction.Response; var res = transaction.Response;
Assert.Equal(HttpStatusCode.Redirect, res.StatusCode); Assert.Equal(HttpStatusCode.Redirect, res.StatusCode);
@ -161,7 +170,7 @@ namespace Microsoft.AspNetCore.Authentication.Tests.MicrosoftAccount
[Fact] [Fact]
public async Task ChallengeWillIncludeScopeAsOverwrittenWithBaseAuthenticationProperties() public async Task ChallengeWillIncludeScopeAsOverwrittenWithBaseAuthenticationProperties()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ClientId = "Test Id"; o.ClientId = "Test Id";
o.ClientSecret = "Test Secret"; o.ClientSecret = "Test Secret";
@ -169,6 +178,7 @@ namespace Microsoft.AspNetCore.Authentication.Tests.MicrosoftAccount
o.Scope.Add("foo"); o.Scope.Add("foo");
o.Scope.Add("bar"); o.Scope.Add("bar");
}); });
using var server = host.GetTestServer();
var transaction = await server.SendAsync("http://example.com/challengeWithOtherScopeWithBaseAuthenticationProperties"); var transaction = await server.SendAsync("http://example.com/challengeWithOtherScopeWithBaseAuthenticationProperties");
var res = transaction.Response; var res = transaction.Response;
Assert.Equal(HttpStatusCode.Redirect, res.StatusCode); Assert.Equal(HttpStatusCode.Redirect, res.StatusCode);
@ -179,7 +189,7 @@ namespace Microsoft.AspNetCore.Authentication.Tests.MicrosoftAccount
public async Task AuthenticatedEventCanGetRefreshToken() public async Task AuthenticatedEventCanGetRefreshToken()
{ {
var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("MsftTest")); var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("MsftTest"));
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ClientId = "Test Client Id"; o.ClientId = "Test Client Id";
o.ClientSecret = "Test Client Secret"; o.ClientSecret = "Test Client Secret";
@ -229,6 +239,7 @@ namespace Microsoft.AspNetCore.Authentication.Tests.MicrosoftAccount
properties.Items.Add(correlationKey, correlationValue); properties.Items.Add(correlationKey, correlationValue);
properties.RedirectUri = "/me"; properties.RedirectUri = "/me";
var state = stateFormat.Protect(properties); var state = stateFormat.Protect(properties);
using var server = host.GetTestServer();
var transaction = await server.SendAsync( var transaction = await server.SendAsync(
"https://example.com/signin-microsoft?code=TestCode&state=" + UrlEncoder.Default.Encode(state), "https://example.com/signin-microsoft?code=TestCode&state=" + UrlEncoder.Default.Encode(state),
$".AspNetCore.Correlation.Microsoft.{correlationValue}=N"); $".AspNetCore.Correlation.Microsoft.{correlationValue}=N");
@ -248,12 +259,13 @@ namespace Microsoft.AspNetCore.Authentication.Tests.MicrosoftAccount
public async Task ChallengeWillUseAuthenticationPropertiesParametersAsQueryArguments() public async Task ChallengeWillUseAuthenticationPropertiesParametersAsQueryArguments()
{ {
var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("MicrosoftTest")); var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("MicrosoftTest"));
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ClientId = "Test Id"; o.ClientId = "Test Id";
o.ClientSecret = "Test Secret"; o.ClientSecret = "Test Secret";
o.StateDataFormat = stateFormat; o.StateDataFormat = stateFormat;
}); });
using var server = host.GetTestServer();
var transaction = await server.SendAsync("https://example.com/challenge"); var transaction = await server.SendAsync("https://example.com/challenge");
Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
@ -277,7 +289,7 @@ namespace Microsoft.AspNetCore.Authentication.Tests.MicrosoftAccount
[Fact] [Fact]
public async Task PkceSentToTokenEndpoint() public async Task PkceSentToTokenEndpoint()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ClientId = "Test Client Id"; o.ClientId = "Test Client Id";
o.ClientSecret = "Test Client Secret"; o.ClientSecret = "Test Client Secret";
@ -320,6 +332,7 @@ namespace Microsoft.AspNetCore.Authentication.Tests.MicrosoftAccount
} }
}; };
}); });
using var server = host.GetTestServer();
var transaction = await server.SendAsync("https://example.com/challenge"); var transaction = await server.SendAsync("https://example.com/challenge");
Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
var locationUri = transaction.Response.Headers.Location; var locationUri = transaction.Response.Headers.Location;
@ -342,9 +355,11 @@ namespace Microsoft.AspNetCore.Authentication.Tests.MicrosoftAccount
Assert.StartsWith(".AspNetCore." + TestExtensions.CookieAuthenticationScheme, transaction.SetCookie[1]); Assert.StartsWith(".AspNetCore." + TestExtensions.CookieAuthenticationScheme, transaction.SetCookie[1]);
} }
private static TestServer CreateServer(Action<MicrosoftAccountOptions> configureOptions) private static async Task<IHost> CreateHost(Action<MicrosoftAccountOptions> configureOptions)
{ {
var builder = new WebHostBuilder() var host = new HostBuilder()
.ConfigureWebHost(builder =>
builder.UseTestServer()
.Configure(app => .Configure(app =>
{ {
app.UseAuthentication(); app.UseAuthentication();
@ -402,8 +417,10 @@ namespace Microsoft.AspNetCore.Authentication.Tests.MicrosoftAccount
services.AddAuthentication(TestExtensions.CookieAuthenticationScheme) services.AddAuthentication(TestExtensions.CookieAuthenticationScheme)
.AddCookie(TestExtensions.CookieAuthenticationScheme, o => { }) .AddCookie(TestExtensions.CookieAuthenticationScheme, o => { })
.AddMicrosoftAccount(configureOptions); .AddMicrosoftAccount(configureOptions);
}); }))
return new TestServer(builder); .Build();
await host.StartAsync();
return host;
} }
private static HttpResponseMessage ReturnJsonResponse(object content) private static HttpResponseMessage ReturnJsonResponse(object content)

View File

@ -7,6 +7,7 @@ using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.TestHost; using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Net; using System.Net;
@ -34,7 +35,7 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
[Fact] [Fact]
public async Task ThrowsIfClientIdMissing() public async Task ThrowsIfClientIdMissing()
{ {
var server = CreateServer( using var host = await CreateHost(
services => services.AddAuthentication().AddOAuth("weeblie", o => services => services.AddAuthentication().AddOAuth("weeblie", o =>
{ {
o.SignInScheme = "whatever"; o.SignInScheme = "whatever";
@ -43,13 +44,14 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
o.TokenEndpoint = "/"; o.TokenEndpoint = "/";
o.AuthorizationEndpoint = "/"; o.AuthorizationEndpoint = "/";
})); }));
using var server = host.GetTestServer();
await Assert.ThrowsAsync<ArgumentException>("ClientId", () => server.SendAsync("http://example.com/")); await Assert.ThrowsAsync<ArgumentException>("ClientId", () => server.SendAsync("http://example.com/"));
} }
[Fact] [Fact]
public async Task ThrowsIfClientSecretMissing() public async Task ThrowsIfClientSecretMissing()
{ {
var server = CreateServer( using var host = await CreateHost(
services => services.AddAuthentication().AddOAuth("weeblie", o => services => services.AddAuthentication().AddOAuth("weeblie", o =>
{ {
o.SignInScheme = "whatever"; o.SignInScheme = "whatever";
@ -58,13 +60,14 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
o.TokenEndpoint = "/"; o.TokenEndpoint = "/";
o.AuthorizationEndpoint = "/"; o.AuthorizationEndpoint = "/";
})); }));
using var server = host.GetTestServer();
await Assert.ThrowsAsync<ArgumentException>("ClientSecret", () => server.SendAsync("http://example.com/")); await Assert.ThrowsAsync<ArgumentException>("ClientSecret", () => server.SendAsync("http://example.com/"));
} }
[Fact] [Fact]
public async Task ThrowsIfCallbackPathMissing() public async Task ThrowsIfCallbackPathMissing()
{ {
var server = CreateServer( using var host = await CreateHost(
services => services.AddAuthentication().AddOAuth("weeblie", o => services => services.AddAuthentication().AddOAuth("weeblie", o =>
{ {
o.ClientId = "Whatever;"; o.ClientId = "Whatever;";
@ -73,13 +76,14 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
o.AuthorizationEndpoint = "/"; o.AuthorizationEndpoint = "/";
o.SignInScheme = "eh"; o.SignInScheme = "eh";
})); }));
using var server = host.GetTestServer();
await Assert.ThrowsAsync<ArgumentException>("CallbackPath", () => server.SendAsync("http://example.com/")); await Assert.ThrowsAsync<ArgumentException>("CallbackPath", () => server.SendAsync("http://example.com/"));
} }
[Fact] [Fact]
public async Task ThrowsIfTokenEndpointMissing() public async Task ThrowsIfTokenEndpointMissing()
{ {
var server = CreateServer( using var host = await CreateHost(
services => services.AddAuthentication().AddOAuth("weeblie", o => services => services.AddAuthentication().AddOAuth("weeblie", o =>
{ {
o.ClientId = "Whatever;"; o.ClientId = "Whatever;";
@ -88,13 +92,14 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
o.AuthorizationEndpoint = "/"; o.AuthorizationEndpoint = "/";
o.SignInScheme = "eh"; o.SignInScheme = "eh";
})); }));
using var server = host.GetTestServer();
await Assert.ThrowsAsync<ArgumentException>("TokenEndpoint", () => server.SendAsync("http://example.com/")); await Assert.ThrowsAsync<ArgumentException>("TokenEndpoint", () => server.SendAsync("http://example.com/"));
} }
[Fact] [Fact]
public async Task ThrowsIfAuthorizationEndpointMissing() public async Task ThrowsIfAuthorizationEndpointMissing()
{ {
var server = CreateServer( using var host = await CreateHost(
services => services.AddAuthentication().AddOAuth("weeblie", o => services => services.AddAuthentication().AddOAuth("weeblie", o =>
{ {
o.ClientId = "Whatever;"; o.ClientId = "Whatever;";
@ -103,13 +108,14 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
o.TokenEndpoint = "/"; o.TokenEndpoint = "/";
o.SignInScheme = "eh"; o.SignInScheme = "eh";
})); }));
using var server = host.GetTestServer();
await Assert.ThrowsAsync<ArgumentException>("AuthorizationEndpoint", () => server.SendAsync("http://example.com/")); await Assert.ThrowsAsync<ArgumentException>("AuthorizationEndpoint", () => server.SendAsync("http://example.com/"));
} }
[Fact] [Fact]
public async Task RedirectToIdentityProvider_SetsCorrelationIdCookiePath_ToCallBackPath() public async Task RedirectToIdentityProvider_SetsCorrelationIdCookiePath_ToCallBackPath()
{ {
var server = CreateServer( using var host = await CreateHost(
s => s.AddAuthentication().AddOAuth( s => s.AddAuthentication().AddOAuth(
"Weblie", "Weblie",
opt => opt =>
@ -122,6 +128,7 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
return true; return true;
}); });
using var server = host.GetTestServer();
var transaction = await server.SendAsync("https://www.example.com/challenge"); var transaction = await server.SendAsync("https://www.example.com/challenge");
var res = transaction.Response; var res = transaction.Response;
@ -135,7 +142,7 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
[Fact] [Fact]
public async Task RedirectToAuthorizeEndpoint_CorrelationIdCookieOptions_CanBeOverriden() public async Task RedirectToAuthorizeEndpoint_CorrelationIdCookieOptions_CanBeOverriden()
{ {
var server = CreateServer( using var host = await CreateHost(
s => s.AddAuthentication().AddOAuth( s => s.AddAuthentication().AddOAuth(
"Weblie", "Weblie",
opt => opt =>
@ -149,6 +156,7 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
return true; return true;
}); });
using var server = host.GetTestServer();
var transaction = await server.SendAsync("https://www.example.com/challenge"); var transaction = await server.SendAsync("https://www.example.com/challenge");
var res = transaction.Response; var res = transaction.Response;
@ -162,7 +170,7 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
[Fact] [Fact]
public async Task RedirectToAuthorizeEndpoint_HasScopeAsConfigured() public async Task RedirectToAuthorizeEndpoint_HasScopeAsConfigured()
{ {
var server = CreateServer( using var host = await CreateHost(
s => s.AddAuthentication().AddOAuth( s => s.AddAuthentication().AddOAuth(
"Weblie", "Weblie",
opt => opt =>
@ -178,6 +186,7 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
return true; return true;
}); });
using var server = host.GetTestServer();
var transaction = await server.SendAsync("https://www.example.com/challenge"); var transaction = await server.SendAsync("https://www.example.com/challenge");
var res = transaction.Response; var res = transaction.Response;
@ -188,7 +197,7 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
[Fact] [Fact]
public async Task RedirectToAuthorizeEndpoint_HasScopeAsOverwritten() public async Task RedirectToAuthorizeEndpoint_HasScopeAsOverwritten()
{ {
var server = CreateServer( using var host = await CreateHost(
s => s.AddAuthentication().AddOAuth( s => s.AddAuthentication().AddOAuth(
"Weblie", "Weblie",
opt => opt =>
@ -206,6 +215,7 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
return true; return true;
}); });
using var server = host.GetTestServer();
var transaction = await server.SendAsync("https://www.example.com/challenge"); var transaction = await server.SendAsync("https://www.example.com/challenge");
var res = transaction.Response; var res = transaction.Response;
@ -216,7 +226,7 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
[Fact] [Fact]
public async Task RedirectToAuthorizeEndpoint_HasScopeAsOverwrittenWithBaseAuthenticationProperties() public async Task RedirectToAuthorizeEndpoint_HasScopeAsOverwrittenWithBaseAuthenticationProperties()
{ {
var server = CreateServer( using var host = await CreateHost(
s => s.AddAuthentication().AddOAuth( s => s.AddAuthentication().AddOAuth(
"Weblie", "Weblie",
opt => opt =>
@ -234,6 +244,7 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
return true; return true;
}); });
using var server = host.GetTestServer();
var transaction = await server.SendAsync("https://www.example.com/challenge"); var transaction = await server.SendAsync("https://www.example.com/challenge");
var res = transaction.Response; var res = transaction.Response;
@ -254,7 +265,7 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
[Fact] [Fact]
public async Task HandleRequestAsync_RedirectsToAccessDeniedPathWhenExplicitlySet() public async Task HandleRequestAsync_RedirectsToAccessDeniedPathWhenExplicitlySet()
{ {
var server = CreateServer( using var host = await CreateHost(
s => s.AddAuthentication().AddOAuth( s => s.AddAuthentication().AddOAuth(
"Weblie", "Weblie",
opt => opt =>
@ -270,6 +281,7 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
opt.Events.OnRemoteFailure = context => throw new InvalidOperationException("This event should not be called."); opt.Events.OnRemoteFailure = context => throw new InvalidOperationException("This event should not be called.");
})); }));
using var server = host.GetTestServer();
var transaction = await server.SendAsync("https://www.example.com/oauth-callback?error=access_denied&state=protected_state", var transaction = await server.SendAsync("https://www.example.com/oauth-callback?error=access_denied&state=protected_state",
".AspNetCore.Correlation.Weblie.correlationId=N"); ".AspNetCore.Correlation.Weblie.correlationId=N");
@ -280,7 +292,7 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
[Fact] [Fact]
public async Task HandleRequestAsync_InvokesAccessDeniedEvent() public async Task HandleRequestAsync_InvokesAccessDeniedEvent()
{ {
var server = CreateServer( using var host = await CreateHost(
s => s.AddAuthentication().AddOAuth( s => s.AddAuthentication().AddOAuth(
"Weblie", "Weblie",
opt => opt =>
@ -304,6 +316,7 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
}; };
})); }));
using var server = host.GetTestServer();
var transaction = await server.SendAsync("https://www.example.com/oauth-callback?error=access_denied&state=protected_state", var transaction = await server.SendAsync("https://www.example.com/oauth-callback?error=access_denied&state=protected_state",
".AspNetCore.Correlation.Weblie.correlationId=N"); ".AspNetCore.Correlation.Weblie.correlationId=N");
@ -314,7 +327,7 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
[Fact] [Fact]
public async Task HandleRequestAsync_InvokesRemoteFailureEventWhenAccessDeniedPathIsNotExplicitlySet() public async Task HandleRequestAsync_InvokesRemoteFailureEventWhenAccessDeniedPathIsNotExplicitlySet()
{ {
var server = CreateServer( using var host = await CreateHost(
s => s.AddAuthentication().AddOAuth( s => s.AddAuthentication().AddOAuth(
"Weblie", "Weblie",
opt => opt =>
@ -339,6 +352,7 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
}; };
})); }));
using var server = host.GetTestServer();
var transaction = await server.SendAsync("https://www.example.com/oauth-callback?error=access_denied&state=protected_state", var transaction = await server.SendAsync("https://www.example.com/oauth-callback?error=access_denied&state=protected_state",
".AspNetCore.Correlation.Weblie.correlationId=N"); ".AspNetCore.Correlation.Weblie.correlationId=N");
@ -349,7 +363,7 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
[Fact] [Fact]
public async Task RemoteAuthenticationFailed_OAuthError_IncludesProperties() public async Task RemoteAuthenticationFailed_OAuthError_IncludesProperties()
{ {
var server = CreateServer( using var host = await CreateHost(
s => s.AddAuthentication().AddOAuth( s => s.AddAuthentication().AddOAuth(
"Weblie", "Weblie",
opt => opt =>
@ -374,6 +388,7 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
}; };
})); }));
using var server = host.GetTestServer();
var transaction = await server.SendAsync("https://www.example.com/oauth-callback?error=custom_error&state=protected_state", var transaction = await server.SendAsync("https://www.example.com/oauth-callback?error=custom_error&state=protected_state",
".AspNetCore.Correlation.Weblie.correlationId=N"); ".AspNetCore.Correlation.Weblie.correlationId=N");
@ -381,9 +396,11 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
Assert.Null(transaction.Response.Headers.Location); Assert.Null(transaction.Response.Headers.Location);
} }
private static TestServer CreateServer(Action<IServiceCollection> configureServices, Func<HttpContext, Task<bool>> handler = null) private static async Task<IHost> CreateHost(Action<IServiceCollection> configureServices, Func<HttpContext, Task<bool>> handler = null)
{ {
var builder = new WebHostBuilder() var host = new HostBuilder()
.ConfigureWebHost(builder =>
builder.UseTestServer()
.Configure(app => .Configure(app =>
{ {
app.UseAuthentication(); app.UseAuthentication();
@ -395,8 +412,10 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
} }
}); });
}) })
.ConfigureServices(configureServices); .ConfigureServices(configureServices))
return new TestServer(builder); .Build();
await host.StartAsync();
return host;
} }
private class TestStateDataFormat : ISecureDataFormat<AuthenticationProperties> private class TestStateDataFormat : ISecureDataFormat<AuthenticationProperties>

View File

@ -12,6 +12,7 @@ using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.TestHost; using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Xunit; using Xunit;
namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect
@ -550,16 +551,19 @@ namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect
private TestServer BuildTestServer(Action<OpenIdConnectOptions> options) private TestServer BuildTestServer(Action<OpenIdConnectOptions> options)
{ {
var builder = new WebHostBuilder() var host = new HostBuilder()
.ConfigureWebHost(builder =>
builder.UseTestServer()
.ConfigureServices(services => .ConfigureServices(services =>
{ {
services.AddAuthentication() services.AddAuthentication()
.AddCookie() .AddCookie()
.AddOpenIdConnect(options); .AddOpenIdConnect(options);
}) })
.Configure(app => app.UseAuthentication()); .Configure(app => app.UseAuthentication()))
.Build();
return new TestServer(builder); host.Start();
return host.GetTestServer();
} }
private async Task TestConfigurationException<T>( private async Task TestConfigurationException<T>(

View File

@ -1,4 +1,4 @@
// Copyright (c) .NET Foundation. All rights reserved. // Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
@ -18,6 +18,7 @@ using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.TestHost; using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Primitives; using Microsoft.Extensions.Primitives;
using Microsoft.IdentityModel.Protocols.OpenIdConnect; using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Microsoft.IdentityModel.Tokens; using Microsoft.IdentityModel.Tokens;
@ -1266,7 +1267,9 @@ namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect
private TestServer CreateServer(OpenIdConnectEvents events, RequestDelegate appCode) private TestServer CreateServer(OpenIdConnectEvents events, RequestDelegate appCode)
{ {
var builder = new WebHostBuilder() var host = new HostBuilder()
.ConfigureWebHost(builder =>
builder.UseTestServer()
.ConfigureServices(services => .ConfigureServices(services =>
{ {
services.AddAuthentication(auth => services.AddAuthentication(auth =>
@ -1296,9 +1299,11 @@ namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect
{ {
app.UseAuthentication(); app.UseAuthentication();
app.Run(appCode); app.Run(appCode);
}); }))
.Build();
return new TestServer(builder); host.Start();
return host.GetTestServer();
} }
private Task<HttpResponseMessage> PostAsync(TestServer server, string path, string form) private Task<HttpResponseMessage> PostAsync(TestServer server, string path, string form)

View File

@ -11,6 +11,7 @@ using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.TestHost; using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.IdentityModel.Protocols; using Microsoft.IdentityModel.Protocols;
using Microsoft.IdentityModel.Protocols.OpenIdConnect; using Microsoft.IdentityModel.Protocols.OpenIdConnect;
@ -62,7 +63,9 @@ namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect
Func<HttpContext, Task> handler, Func<HttpContext, Task> handler,
AuthenticationProperties properties) AuthenticationProperties properties)
{ {
var builder = new WebHostBuilder() var host = new HostBuilder()
.ConfigureWebHost(builder =>
builder.UseTestServer()
.Configure(app => .Configure(app =>
{ {
app.UseAuthentication(); app.UseAuthentication();
@ -112,9 +115,11 @@ namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie() .AddCookie()
.AddOpenIdConnect(options); .AddOpenIdConnect(options);
}); }))
.Build();
return new TestServer(builder); host.Start();
return host.GetTestServer();
} }
} }
} }

View File

@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.TestHost; using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Xunit; using Xunit;
@ -16,8 +17,8 @@ namespace Microsoft.AspNetCore.Authentication
{ {
protected override string DisplayName => DefaultScheme; protected override string DisplayName => DefaultScheme;
private TestServer CreateServer(Action<TOptions> configureOptions, Func<HttpContext, Task> testpath = null, bool isDefault = true) private Task<IHost> CreateHost(Action<TOptions> configureOptions, Func<HttpContext, Task> testpath = null, bool isDefault = true)
=> CreateServerWithServices(s => => CreateHostWithServices(s =>
{ {
var builder = s.AddAuthentication(); var builder = s.AddAuthentication();
if (isDefault) if (isDefault)
@ -29,10 +30,11 @@ namespace Microsoft.AspNetCore.Authentication
}, testpath); }, testpath);
protected virtual TestServer CreateServerWithServices(Action<IServiceCollection> configureServices, Func<HttpContext, Task> testpath = null) protected virtual async Task<IHost> CreateHostWithServices(Action<IServiceCollection> configureServices, Func<HttpContext, Task> testpath = null)
{ {
//private static TestServer CreateServer(Action<IApplicationBuilder> configure, Action<IServiceCollection> configureServices, Func<HttpContext, Task<bool>> handler) var host = new HostBuilder()
var builder = new WebHostBuilder() .ConfigureWebHost(webHostBuilder =>
webHostBuilder.UseTestServer()
.Configure(app => .Configure(app =>
{ {
app.Use(async (context, next) => app.Use(async (context, next) =>
@ -44,8 +46,10 @@ namespace Microsoft.AspNetCore.Authentication
await next(); await next();
}); });
}) })
.ConfigureServices(configureServices); .ConfigureServices(configureServices))
return new TestServer(builder); .Build();
await host.StartAsync();
return host;
} }
protected abstract void ConfigureDefaults(TOptions o); protected abstract void ConfigureDefaults(TOptions o);
@ -53,13 +57,14 @@ namespace Microsoft.AspNetCore.Authentication
[Fact] [Fact]
public async Task VerifySignInSchemeCannotBeSetToSelf() public async Task VerifySignInSchemeCannotBeSetToSelf()
{ {
var server = CreateServer( using var host = await CreateHost(
o => o =>
{ {
ConfigureDefaults(o); ConfigureDefaults(o);
o.SignInScheme = DefaultScheme; o.SignInScheme = DefaultScheme;
}, },
context => context.ChallengeAsync(DefaultScheme)); context => context.ChallengeAsync(DefaultScheme));
using var server = host.GetTestServer();
var error = await Assert.ThrowsAsync<InvalidOperationException>(() => server.SendAsync("https://example.com/challenge")); var error = await Assert.ThrowsAsync<InvalidOperationException>(() => server.SendAsync("https://example.com/challenge"));
Assert.Contains("cannot be set to itself", error.Message); Assert.Contains("cannot be set to itself", error.Message);
} }
@ -67,10 +72,12 @@ namespace Microsoft.AspNetCore.Authentication
[Fact] [Fact]
public async Task VerifySignInSchemeCannotBeSetToSelfUsingDefaultScheme() public async Task VerifySignInSchemeCannotBeSetToSelfUsingDefaultScheme()
{ {
var server = CreateServer(
using var host = await CreateHost(
o => o.SignInScheme = null, o => o.SignInScheme = null,
context => context.ChallengeAsync(DefaultScheme), context => context.ChallengeAsync(DefaultScheme),
isDefault: true); isDefault: true);
using var server = host.GetTestServer();
var error = await Assert.ThrowsAsync<InvalidOperationException>(() => server.SendAsync("https://example.com/challenge")); var error = await Assert.ThrowsAsync<InvalidOperationException>(() => server.SendAsync("https://example.com/challenge"));
Assert.Contains("cannot be set to itself", error.Message); Assert.Contains("cannot be set to itself", error.Message);
} }
@ -78,13 +85,14 @@ namespace Microsoft.AspNetCore.Authentication
[Fact] [Fact]
public async Task VerifySignInSchemeCannotBeSetToSelfUsingDefaultSignInScheme() public async Task VerifySignInSchemeCannotBeSetToSelfUsingDefaultSignInScheme()
{ {
var server = CreateServerWithServices( using var host = await CreateHostWithServices(
services => services =>
{ {
var builder = services.AddAuthentication(o => o.DefaultSignInScheme = DefaultScheme); var builder = services.AddAuthentication(o => o.DefaultSignInScheme = DefaultScheme);
RegisterAuth(builder, o => o.SignInScheme = null); RegisterAuth(builder, o => o.SignInScheme = null);
}, },
context => context.ChallengeAsync(DefaultScheme)); context => context.ChallengeAsync(DefaultScheme));
using var server = host.GetTestServer();
var error = await Assert.ThrowsAsync<InvalidOperationException>(() => server.SendAsync("https://example.com/challenge")); var error = await Assert.ThrowsAsync<InvalidOperationException>(() => server.SendAsync("https://example.com/challenge"));
Assert.Contains("cannot be set to itself", error.Message); Assert.Contains("cannot be set to itself", error.Message);
} }

View File

@ -5,6 +5,7 @@ using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.TestHost; using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Net.Http.Headers; using Microsoft.Net.Http.Headers;
using System; using System;
using System.Linq; using System.Linq;
@ -43,7 +44,7 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
[Fact] [Fact]
public async Task ChallengeWillTriggerApplyRedirectEvent() public async Task ChallengeWillTriggerApplyRedirectEvent()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ConsumerKey = "Test Consumer Key"; o.ConsumerKey = "Test Consumer Key";
o.ConsumerSecret = "Test Consumer Secret"; o.ConsumerSecret = "Test Consumer Secret";
@ -65,6 +66,7 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
await context.ChallengeAsync("Twitter"); await context.ChallengeAsync("Twitter");
return true; return true;
}); });
using var server = host.GetTestServer();
var transaction = await server.SendAsync("http://example.com/challenge"); var transaction = await server.SendAsync("http://example.com/challenge");
Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
var query = transaction.Response.Headers.Location.Query; var query = transaction.Response.Headers.Location.Query;
@ -78,11 +80,12 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
[Fact] [Fact]
public async Task ThrowsIfClientIdMissing() public async Task ThrowsIfClientIdMissing()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ConsumerSecret = "Test Consumer Secret"; o.ConsumerSecret = "Test Consumer Secret";
}); });
using var server = host.GetTestServer();
await Assert.ThrowsAsync<ArgumentException>("ConsumerKey", async () => await server.SendAsync("http://example.com/challenge")); await Assert.ThrowsAsync<ArgumentException>("ConsumerKey", async () => await server.SendAsync("http://example.com/challenge"));
} }
@ -93,24 +96,26 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
[Fact] [Fact]
public async Task ThrowsIfClientSecretMissing() public async Task ThrowsIfClientSecretMissing()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ConsumerKey = "Test Consumer Key"; o.ConsumerKey = "Test Consumer Key";
}); });
using var server = host.GetTestServer();
await Assert.ThrowsAsync<ArgumentException>("ConsumerSecret", async () => await server.SendAsync("http://example.com/challenge")); await Assert.ThrowsAsync<ArgumentException>("ConsumerSecret", async () => await server.SendAsync("http://example.com/challenge"));
} }
[Fact] [Fact]
public async Task BadSignInWillThrow() public async Task BadSignInWillThrow()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ConsumerKey = "Test Consumer Key"; o.ConsumerKey = "Test Consumer Key";
o.ConsumerSecret = "Test Consumer Secret"; o.ConsumerSecret = "Test Consumer Secret";
}); });
// Send a bogus sign in // Send a bogus sign in
using var server = host.GetTestServer();
var error = await Assert.ThrowsAnyAsync<Exception>(() => server.SendAsync("https://example.com/signin-twitter")); var error = await Assert.ThrowsAnyAsync<Exception>(() => server.SendAsync("https://example.com/signin-twitter"));
Assert.Equal("Invalid state cookie.", error.GetBaseException().Message); Assert.Equal("Invalid state cookie.", error.GetBaseException().Message);
} }
@ -118,11 +123,12 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
[Fact] [Fact]
public async Task SignInThrows() public async Task SignInThrows()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ConsumerKey = "Test Consumer Key"; o.ConsumerKey = "Test Consumer Key";
o.ConsumerSecret = "Test Consumer Secret"; o.ConsumerSecret = "Test Consumer Secret";
}); });
using var server = host.GetTestServer();
var transaction = await server.SendAsync("https://example.com/signIn"); var transaction = await server.SendAsync("https://example.com/signIn");
Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode);
} }
@ -130,11 +136,12 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
[Fact] [Fact]
public async Task SignOutThrows() public async Task SignOutThrows()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ConsumerKey = "Test Consumer Key"; o.ConsumerKey = "Test Consumer Key";
o.ConsumerSecret = "Test Consumer Secret"; o.ConsumerSecret = "Test Consumer Secret";
}); });
using var server = host.GetTestServer();
var transaction = await server.SendAsync("https://example.com/signOut"); var transaction = await server.SendAsync("https://example.com/signOut");
Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode);
} }
@ -142,11 +149,12 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
[Fact] [Fact]
public async Task ForbidThrows() public async Task ForbidThrows()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ConsumerKey = "Test Consumer Key"; o.ConsumerKey = "Test Consumer Key";
o.ConsumerSecret = "Test Consumer Secret"; o.ConsumerSecret = "Test Consumer Secret";
}); });
using var server = host.GetTestServer();
var transaction = await server.SendAsync("https://example.com/signOut"); var transaction = await server.SendAsync("https://example.com/signOut");
Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode);
} }
@ -154,7 +162,7 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
[Fact] [Fact]
public async Task ChallengeWillTriggerRedirection() public async Task ChallengeWillTriggerRedirection()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ConsumerKey = "Test Consumer Key"; o.ConsumerKey = "Test Consumer Key";
o.ConsumerSecret = "Test Consumer Secret"; o.ConsumerSecret = "Test Consumer Secret";
@ -168,6 +176,7 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
await context.ChallengeAsync("Twitter"); await context.ChallengeAsync("Twitter");
return true; return true;
}); });
using var server = host.GetTestServer();
var transaction = await server.SendAsync("http://example.com/challenge"); var transaction = await server.SendAsync("http://example.com/challenge");
Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
var location = transaction.Response.Headers.Location.AbsoluteUri; var location = transaction.Response.Headers.Location.AbsoluteUri;
@ -177,7 +186,7 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
[Fact] [Fact]
public async Task HandleRequestAsync_RedirectsToAccessDeniedPathWhenExplicitlySet() public async Task HandleRequestAsync_RedirectsToAccessDeniedPathWhenExplicitlySet()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ConsumerKey = "Test Consumer Key"; o.ConsumerKey = "Test Consumer Key";
o.ConsumerSecret = "Test Consumer Secret"; o.ConsumerSecret = "Test Consumer Secret";
@ -195,6 +204,7 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
await context.ChallengeAsync("Twitter", properties); await context.ChallengeAsync("Twitter", properties);
return true; return true;
}); });
using var server = host.GetTestServer();
var transaction = await server.SendAsync("http://example.com/challenge"); var transaction = await server.SendAsync("http://example.com/challenge");
Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
var location = transaction.Response.Headers.Location.AbsoluteUri; var location = transaction.Response.Headers.Location.AbsoluteUri;
@ -217,7 +227,7 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
[Fact] [Fact]
public async Task BadCallbackCallsAccessDeniedWithState() public async Task BadCallbackCallsAccessDeniedWithState()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ConsumerKey = "Test Consumer Key"; o.ConsumerKey = "Test Consumer Key";
o.ConsumerSecret = "Test Consumer Secret"; o.ConsumerSecret = "Test Consumer Secret";
@ -244,6 +254,7 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
await context.ChallengeAsync("Twitter", properties); await context.ChallengeAsync("Twitter", properties);
return true; return true;
}); });
using var server = host.GetTestServer();
var transaction = await server.SendAsync("http://example.com/challenge"); var transaction = await server.SendAsync("http://example.com/challenge");
Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
var location = transaction.Response.Headers.Location.AbsoluteUri; var location = transaction.Response.Headers.Location.AbsoluteUri;
@ -265,7 +276,7 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
[Fact] [Fact]
public async Task BadCallbackCallsRemoteAuthFailedWithState() public async Task BadCallbackCallsRemoteAuthFailedWithState()
{ {
var server = CreateServer(o => using var host = await CreateHost(o =>
{ {
o.ConsumerKey = "Test Consumer Key"; o.ConsumerKey = "Test Consumer Key";
o.ConsumerSecret = "Test Consumer Secret"; o.ConsumerSecret = "Test Consumer Secret";
@ -294,6 +305,8 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
await context.ChallengeAsync("Twitter", properties); await context.ChallengeAsync("Twitter", properties);
return true; return true;
}); });
using var server = host.GetTestServer();
var transaction = await server.SendAsync("http://example.com/challenge"); var transaction = await server.SendAsync("http://example.com/challenge");
Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode); Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
var location = transaction.Response.Headers.Location.AbsoluteUri; var location = transaction.Response.Headers.Location.AbsoluteUri;
@ -312,9 +325,11 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
Assert.Equal(HttpStatusCode.NotAcceptable, response.StatusCode); Assert.Equal(HttpStatusCode.NotAcceptable, response.StatusCode);
} }
private static TestServer CreateServer(Action<TwitterOptions> options, Func<HttpContext, Task<bool>> handler = null) private static async Task<IHost> CreateHost(Action<TwitterOptions> options, Func<HttpContext, Task<bool>> handler = null)
{ {
var builder = new WebHostBuilder() var host = new HostBuilder()
.ConfigureWebHost(builder =>
builder.UseTestServer()
.Configure(app => .Configure(app =>
{ {
app.UseAuthentication(); app.UseAuthentication();
@ -350,8 +365,11 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
services.AddAuthentication() services.AddAuthentication()
.AddCookie("External", _ => { }) .AddCookie("External", _ => { })
.AddTwitter(wrapOptions); .AddTwitter(wrapOptions);
}); }))
return new TestServer(builder); .Build();
await host.StartAsync();
return host;
} }
private HttpResponseMessage BackchannelRequestToken(HttpRequestMessage req) private HttpResponseMessage BackchannelRequestToken(HttpRequestMessage req)

View File

@ -19,6 +19,7 @@ using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.TestHost; using Microsoft.AspNetCore.TestHost;
using Microsoft.AspNetCore.WebUtilities; using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.IdentityModel.Tokens; using Microsoft.IdentityModel.Tokens;
using Microsoft.Net.Http.Headers; using Microsoft.Net.Http.Headers;
using Xunit; using Xunit;
@ -43,7 +44,9 @@ namespace Microsoft.AspNetCore.Authentication.WsFederation
[Fact] [Fact]
public async Task MissingConfigurationThrows() public async Task MissingConfigurationThrows()
{ {
var builder = new WebHostBuilder() using var host = new HostBuilder()
.ConfigureWebHost(builder =>
builder.UseTestServer()
.Configure(ConfigureApp) .Configure(ConfigureApp)
.ConfigureServices(services => .ConfigureServices(services =>
{ {
@ -55,8 +58,11 @@ namespace Microsoft.AspNetCore.Authentication.WsFederation
}) })
.AddCookie() .AddCookie()
.AddWsFederation(); .AddWsFederation();
}); }))
var server = new TestServer(builder); .Build();
await host.StartAsync();
using var server = host.GetTestServer();
var httpClient = server.CreateClient(); var httpClient = server.CreateClient();
// Verify if the request is redirected to STS with right parameters // Verify if the request is redirected to STS with right parameters
@ -67,7 +73,7 @@ namespace Microsoft.AspNetCore.Authentication.WsFederation
[Fact] [Fact]
public async Task ChallengeRedirects() public async Task ChallengeRedirects()
{ {
var httpClient = CreateClient(); var httpClient = await CreateClient();
// Verify if the request is redirected to STS with right parameters // Verify if the request is redirected to STS with right parameters
var response = await httpClient.GetAsync("/"); var response = await httpClient.GetAsync("/");
@ -83,7 +89,7 @@ namespace Microsoft.AspNetCore.Authentication.WsFederation
[Fact] [Fact]
public async Task MapWillNotAffectRedirect() public async Task MapWillNotAffectRedirect()
{ {
var httpClient = CreateClient(); var httpClient = await CreateClient();
// Verify if the request is redirected to STS with right parameters // Verify if the request is redirected to STS with right parameters
var response = await httpClient.GetAsync("/mapped-challenge"); var response = await httpClient.GetAsync("/mapped-challenge");
@ -99,7 +105,7 @@ namespace Microsoft.AspNetCore.Authentication.WsFederation
[Fact] [Fact]
public async Task PreMappedWillAffectRedirect() public async Task PreMappedWillAffectRedirect()
{ {
var httpClient = CreateClient(); var httpClient = await CreateClient();
// Verify if the request is redirected to STS with right parameters // Verify if the request is redirected to STS with right parameters
var response = await httpClient.GetAsync("/premapped-challenge"); var response = await httpClient.GetAsync("/premapped-challenge");
@ -115,7 +121,7 @@ namespace Microsoft.AspNetCore.Authentication.WsFederation
[Fact] [Fact]
public async Task ValidTokenIsAccepted() public async Task ValidTokenIsAccepted()
{ {
var httpClient = CreateClient(); var httpClient = await CreateClient();
// Verify if the request is redirected to STS with right parameters // Verify if the request is redirected to STS with right parameters
var response = await httpClient.GetAsync("/"); var response = await httpClient.GetAsync("/");
@ -139,7 +145,7 @@ namespace Microsoft.AspNetCore.Authentication.WsFederation
[Fact] [Fact]
public async Task ValidUnsolicitedTokenIsRefused() public async Task ValidUnsolicitedTokenIsRefused()
{ {
var httpClient = CreateClient(); var httpClient = await CreateClient();
var form = CreateSignInContent("WsFederation/ValidToken.xml", suppressWctx: true); var form = CreateSignInContent("WsFederation/ValidToken.xml", suppressWctx: true);
var exception = await Assert.ThrowsAsync<Exception>(() => httpClient.PostAsync(httpClient.BaseAddress + "signin-wsfed", form)); var exception = await Assert.ThrowsAsync<Exception>(() => httpClient.PostAsync(httpClient.BaseAddress + "signin-wsfed", form));
Assert.Contains("Unsolicited logins are not allowed.", exception.InnerException.Message); Assert.Contains("Unsolicited logins are not allowed.", exception.InnerException.Message);
@ -148,7 +154,7 @@ namespace Microsoft.AspNetCore.Authentication.WsFederation
[Fact] [Fact]
public async Task ValidUnsolicitedTokenIsAcceptedWhenAllowed() public async Task ValidUnsolicitedTokenIsAcceptedWhenAllowed()
{ {
var httpClient = CreateClient(allowUnsolicited: true); var httpClient = await CreateClient(allowUnsolicited: true);
var form = CreateSignInContent("WsFederation/ValidToken.xml", suppressWctx: true); var form = CreateSignInContent("WsFederation/ValidToken.xml", suppressWctx: true);
var response = await httpClient.PostAsync(httpClient.BaseAddress + "signin-wsfed", form); var response = await httpClient.PostAsync(httpClient.BaseAddress + "signin-wsfed", form);
@ -166,7 +172,7 @@ namespace Microsoft.AspNetCore.Authentication.WsFederation
[Fact] [Fact]
public async Task InvalidTokenIsRejected() public async Task InvalidTokenIsRejected()
{ {
var httpClient = CreateClient(); var httpClient = await CreateClient();
// Verify if the request is redirected to STS with right parameters // Verify if the request is redirected to STS with right parameters
var response = await httpClient.GetAsync("/"); var response = await httpClient.GetAsync("/");
@ -184,7 +190,7 @@ namespace Microsoft.AspNetCore.Authentication.WsFederation
[Fact] [Fact]
public async Task RemoteSignoutRequestTriggersSignout() public async Task RemoteSignoutRequestTriggersSignout()
{ {
var httpClient = CreateClient(); var httpClient = await CreateClient();
var response = await httpClient.GetAsync("/signin-wsfed?wa=wsignoutcleanup1.0"); var response = await httpClient.GetAsync("/signin-wsfed?wa=wsignoutcleanup1.0");
response.EnsureSuccessStatusCode(); response.EnsureSuccessStatusCode();
@ -198,7 +204,9 @@ namespace Microsoft.AspNetCore.Authentication.WsFederation
[Fact] [Fact]
public async Task EventsResolvedFromDI() public async Task EventsResolvedFromDI()
{ {
var builder = new WebHostBuilder() using var host = new HostBuilder()
.ConfigureWebHost(builder =>
builder.UseTestServer()
.ConfigureServices(services => .ConfigureServices(services =>
{ {
services.AddSingleton<MyWsFedEvents>(); services.AddSingleton<MyWsFedEvents>();
@ -220,8 +228,11 @@ namespace Microsoft.AspNetCore.Authentication.WsFederation
.Configure(app => .Configure(app =>
{ {
app.Run(context => context.ChallengeAsync()); app.Run(context => context.ChallengeAsync());
}); }))
var server = new TestServer(builder); .Build();
await host.StartAsync();
using var server = host.GetTestServer();
var result = await server.CreateClient().GetAsync(""); var result = await server.CreateClient().GetAsync("");
Assert.Contains("CustomKey=CustomValue", result.Headers.Location.Query); Assert.Contains("CustomKey=CustomValue", result.Headers.Location.Query);
@ -264,9 +275,11 @@ namespace Microsoft.AspNetCore.Authentication.WsFederation
} }
} }
private HttpClient CreateClient(bool allowUnsolicited = false) private async Task<HttpClient> CreateClient(bool allowUnsolicited = false)
{ {
var builder = new WebHostBuilder() var host = new HostBuilder()
.ConfigureWebHost(builder =>
builder.UseTestServer()
.Configure(ConfigureApp) .Configure(ConfigureApp)
.ConfigureServices(services => .ConfigureServices(services =>
{ {
@ -342,8 +355,11 @@ namespace Microsoft.AspNetCore.Authentication.WsFederation
} }
}; };
}); });
}); }))
var server = new TestServer(builder); .Build();
await host.StartAsync();
var server = host.GetTestServer();
return server.CreateClient(); return server.CreateClient();
} }