From 8b7d33baaf3ee2a99ca27ca91a4068e78c48cc66 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Thu, 18 Dec 2014 14:41:16 -0800 Subject: [PATCH] #63 - Use the PathBase in the Cookie path by default. --- .../CookieAuthenticationHandler.cs | 2 +- .../CookieAuthenticationOptions.cs | 1 - .../Cookies/CookieMiddlewareTests.cs | 51 ++++++++++++++----- 3 files changed, 38 insertions(+), 16 deletions(-) diff --git a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs index 63c524afa6..e290232575 100644 --- a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationHandler.cs @@ -146,7 +146,7 @@ namespace Microsoft.AspNet.Security.Cookies { Domain = Options.CookieDomain, HttpOnly = Options.CookieHttpOnly, - Path = Options.CookiePath ?? "/", + Path = Options.CookiePath ?? (RequestPathBase.HasValue ? RequestPathBase.ToString() : "/"), }; if (Options.CookieSecure == CookieSecureOption.SameAsRequest) { diff --git a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationOptions.cs b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationOptions.cs index 121ff409b2..ec6e102063 100644 --- a/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationOptions.cs +++ b/src/Microsoft.AspNet.Security.Cookies/CookieAuthenticationOptions.cs @@ -24,7 +24,6 @@ namespace Microsoft.AspNet.Security.Cookies { AuthenticationType = CookieAuthenticationDefaults.AuthenticationType; ReturnUrlParameter = CookieAuthenticationDefaults.ReturnUrlParameter; - CookiePath = "/"; ExpireTimeSpan = TimeSpan.FromDays(14); SlidingExpiration = true; CookieHttpOnly = true; diff --git a/test/Microsoft.AspNet.Security.Test/Cookies/CookieMiddlewareTests.cs b/test/Microsoft.AspNet.Security.Test/Cookies/CookieMiddlewareTests.cs index b103a7c757..c66d571b28 100644 --- a/test/Microsoft.AspNet.Security.Test/Cookies/CookieMiddlewareTests.cs +++ b/test/Microsoft.AspNet.Security.Test/Cookies/CookieMiddlewareTests.cs @@ -137,21 +137,11 @@ namespace Microsoft.AspNet.Security.Cookies options.CookieDomain = "another.com"; options.CookieSecure = CookieSecureOption.Always; options.CookieHttpOnly = true; - }, SignInAsAlice); + }, SignInAsAlice, new Uri("http://example.com/base")); - Transaction transaction1 = await SendAsync(server1, "http://example.com/testpath"); - - TestServer server2 = CreateServer(options => - { - options.CookieName = "SecondCookie"; - options.CookieSecure = CookieSecureOption.Never; - options.CookieHttpOnly = false; - }, SignInAsAlice); - - Transaction transaction2 = await SendAsync(server2, "http://example.com/testpath"); + Transaction transaction1 = await SendAsync(server1, "http://example.com/base/testpath"); string setCookie1 = transaction1.SetCookie; - string setCookie2 = transaction2.SetCookie; setCookie1.ShouldContain("TestCookie="); setCookie1.ShouldContain(" path=/foo"); @@ -159,7 +149,19 @@ namespace Microsoft.AspNet.Security.Cookies setCookie1.ShouldContain(" secure"); setCookie1.ShouldContain(" HttpOnly"); + TestServer server2 = CreateServer(options => + { + options.CookieName = "SecondCookie"; + options.CookieSecure = CookieSecureOption.Never; + options.CookieHttpOnly = false; + }, SignInAsAlice, new Uri("http://example.com/base")); + + Transaction transaction2 = await SendAsync(server2, "http://example.com/base/testpath"); + + string setCookie2 = transaction2.SetCookie; + setCookie2.ShouldContain("SecondCookie="); + setCookie2.ShouldContain(" path=/base"); setCookie2.ShouldNotContain(" domain="); setCookie2.ShouldNotContain(" secure"); setCookie2.ShouldNotContain(" HttpOnly"); @@ -343,6 +345,25 @@ namespace Microsoft.AspNet.Security.Cookies responded.Single().ShouldContain("\"location\""); } + [Fact] + public async Task CookieUsesPathBaseByDefault() + { + var clock = new TestClock(); + TestServer server = CreateServer(options => + { + }, + context => + { + Assert.Equal(new PathString("/base"), context.Request.PathBase); + context.Response.SignIn(new ClaimsIdentity(new GenericIdentity("Alice", "Cookies"))); + return Task.FromResult(null); + }, + new Uri("http://example.com/base")); + + Transaction transaction1 = await SendAsync(server, "http://example.com/base/testpath"); + Assert.True(transaction1.SetCookie.Contains("path=/base")); + } + private static string FindClaimValue(Transaction transaction, string claimType) { XElement claim = transaction.ResponseElement.Elements("claim").SingleOrDefault(elt => elt.Attribute("type").Value == claimType); @@ -364,9 +385,9 @@ namespace Microsoft.AspNet.Security.Cookies return me; } - private static TestServer CreateServer(Action configureOptions, Func testpath = null) + private static TestServer CreateServer(Action configureOptions, Func testpath = null, Uri baseAddress = null) { - return TestServer.Create(app => + var server = TestServer.Create(app => { app.UseServices(services => services.AddDataProtection()); app.UseCookieAuthentication(configureOptions); @@ -406,6 +427,8 @@ namespace Microsoft.AspNet.Security.Cookies } }); }); + server.BaseAddress = baseAddress; + return server; } private static void Describe(HttpResponse res, AuthenticationResult result)