Use a shared CookieSecurePolicy.

This commit is contained in:
Chris R 2016-05-16 12:18:50 -07:00
parent 1a99fad0c6
commit 6294badd97
8 changed files with 62 additions and 108 deletions

View File

@ -145,13 +145,13 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
HttpOnly = Options.CookieHttpOnly, HttpOnly = Options.CookieHttpOnly,
Path = Options.CookiePath ?? (OriginalPathBase.HasValue ? OriginalPathBase.ToString() : "/"), Path = Options.CookiePath ?? (OriginalPathBase.HasValue ? OriginalPathBase.ToString() : "/"),
}; };
if (Options.CookieSecure == CookieSecureOption.SameAsRequest) if (Options.CookieSecure == CookieSecurePolicy.SameAsRequest)
{ {
cookieOptions.Secure = Request.IsHttps; cookieOptions.Secure = Request.IsHttps;
} }
else else
{ {
cookieOptions.Secure = Options.CookieSecure == CookieSecureOption.Always; cookieOptions.Secure = Options.CookieSecure == CookieSecurePolicy.Always;
} }
return cookieOptions; return cookieOptions;
} }

View File

@ -29,7 +29,7 @@ namespace Microsoft.AspNetCore.Builder
ExpireTimeSpan = TimeSpan.FromDays(14); ExpireTimeSpan = TimeSpan.FromDays(14);
SlidingExpiration = true; SlidingExpiration = true;
CookieHttpOnly = true; CookieHttpOnly = true;
CookieSecure = CookieSecureOption.SameAsRequest; CookieSecure = CookieSecurePolicy.SameAsRequest;
SystemClock = new SystemClock(); SystemClock = new SystemClock();
Events = new CookieAuthenticationEvents(); Events = new CookieAuthenticationEvents();
} }
@ -59,7 +59,7 @@ namespace Microsoft.AspNetCore.Builder
public string CookieDomain { get; set; } public string CookieDomain { get; set; }
/// <summary> /// <summary>
/// Determines the path used to create the cookie. The default value is "/" for highest browser compatability. /// Determines the path used to create the cookie. The default value is "/" for highest browser compatibility.
/// </summary> /// </summary>
public string CookiePath { get; set; } public string CookiePath { get; set; }
@ -75,7 +75,7 @@ namespace Microsoft.AspNetCore.Builder
/// to HTTPS requests if the page which is doing the SignIn is also HTTPS. If you have an HTTPS sign in page /// to HTTPS requests if the page which is doing the SignIn is also HTTPS. If you have an HTTPS sign in page
/// and portions of your site are HTTP you may need to change this value. /// and portions of your site are HTTP you may need to change this value.
/// </summary> /// </summary>
public CookieSecureOption CookieSecure { get; set; } public CookieSecurePolicy CookieSecure { get; set; }
/// <summary> /// <summary>
/// If set this will be used by the CookieAuthenticationMiddleware for data protection. /// If set this will be used by the CookieAuthenticationMiddleware for data protection.

View File

@ -1,35 +0,0 @@
// 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.
namespace Microsoft.AspNetCore.Authentication.Cookies
{
/// <summary>
/// Determines how the identity cookie's security property is set.
/// </summary>
public enum CookieSecureOption
{
/// <summary>
/// If the URI that provides the cookie is HTTPS, then the cookie will only be returned to the server on
/// subsequent HTTPS requests. Otherwise if the URI that provides the cookie is HTTP, then the cookie will
/// be returned to the server on all HTTP and HTTPS requests. This is the default value because it ensures
/// HTTPS for all authenticated requests on deployed servers, and also supports HTTP for localhost development
/// and for servers that do not have HTTPS support.
/// </summary>
SameAsRequest,
/// <summary>
/// CookieOptions.Secure is never marked true. Use this value when your login page is HTTPS, but other pages
/// on the site which are HTTP also require authentication information. This setting is not recommended because
/// the authentication information provided with an HTTP request may be observed and used by other computers
/// on your local network or wireless connection.
/// </summary>
Never,
/// <summary>
/// CookieOptions.Secure is always marked true. Use this value when your login page and all subsequent pages
/// requiring the authenticated identity are HTTPS. Local development will also need to be done with HTTPS urls.
/// </summary>
Always,
}
}

View File

@ -74,7 +74,7 @@ namespace Microsoft.AspNetCore.CookiePolicy
private bool PolicyRequiresCookieOptions() private bool PolicyRequiresCookieOptions()
{ {
return Policy.HttpOnly != HttpOnlyPolicy.None || Policy.Secure != SecurePolicy.None; return Policy.HttpOnly != HttpOnlyPolicy.None || Policy.Secure != CookieSecurePolicy.None;
} }
public void Append(string key, string value) public void Append(string key, string value)
@ -140,13 +140,13 @@ namespace Microsoft.AspNetCore.CookiePolicy
{ {
switch (Policy.Secure) switch (Policy.Secure)
{ {
case SecurePolicy.Always: case CookieSecurePolicy.Always:
options.Secure = true; options.Secure = true;
break; break;
case SecurePolicy.SameAsRequest: case CookieSecurePolicy.SameAsRequest:
options.Secure = Context.Request.IsHttps; options.Secure = Context.Request.IsHttps;
break; break;
case SecurePolicy.None: case CookieSecurePolicy.None:
break; break;
default: default:
throw new InvalidOperationException(); throw new InvalidOperationException();

View File

@ -3,6 +3,7 @@
using System; using System;
using Microsoft.AspNetCore.CookiePolicy; using Microsoft.AspNetCore.CookiePolicy;
using Microsoft.AspNetCore.Http;
namespace Microsoft.AspNetCore.Builder namespace Microsoft.AspNetCore.Builder
{ {
@ -15,10 +16,11 @@ namespace Microsoft.AspNetCore.Builder
/// Affects whether cookies must be HttpOnly. /// Affects whether cookies must be HttpOnly.
/// </summary> /// </summary>
public HttpOnlyPolicy HttpOnly { get; set; } = HttpOnlyPolicy.None; public HttpOnlyPolicy HttpOnly { get; set; } = HttpOnlyPolicy.None;
/// <summary> /// <summary>
/// Affects whether cookies must be Secure. /// Affects whether cookies must be Secure.
/// </summary> /// </summary>
public SecurePolicy Secure { get; set; } = SecurePolicy.None; public CookieSecurePolicy Secure { get; set; } = CookieSecurePolicy.None;
/// <summary> /// <summary>
/// Called when a cookie is appended. /// Called when a cookie is appended.

View File

@ -1,12 +0,0 @@
// 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.
namespace Microsoft.AspNetCore.CookiePolicy
{
public enum SecurePolicy
{
None,
Always,
SameAsRequest
}
}

View File

@ -192,14 +192,14 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
} }
[Theory] [Theory]
[InlineData(CookieSecureOption.Always, "http://example.com/testpath", true)] [InlineData(CookieSecurePolicy.Always, "http://example.com/testpath", true)]
[InlineData(CookieSecureOption.Always, "https://example.com/testpath", true)] [InlineData(CookieSecurePolicy.Always, "https://example.com/testpath", true)]
[InlineData(CookieSecureOption.Never, "http://example.com/testpath", false)] [InlineData(CookieSecurePolicy.None, "http://example.com/testpath", false)]
[InlineData(CookieSecureOption.Never, "https://example.com/testpath", false)] [InlineData(CookieSecurePolicy.None, "https://example.com/testpath", false)]
[InlineData(CookieSecureOption.SameAsRequest, "http://example.com/testpath", false)] [InlineData(CookieSecurePolicy.SameAsRequest, "http://example.com/testpath", false)]
[InlineData(CookieSecureOption.SameAsRequest, "https://example.com/testpath", true)] [InlineData(CookieSecurePolicy.SameAsRequest, "https://example.com/testpath", true)]
public async Task SecureSignInCausesSecureOnlyCookieByDefault( public async Task SecureSignInCausesSecureOnlyCookieByDefault(
CookieSecureOption cookieSecureOption, CookieSecurePolicy cookieSecurePolicy,
string requestUri, string requestUri,
bool shouldBeSecureOnly) bool shouldBeSecureOnly)
{ {
@ -207,7 +207,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
{ {
LoginPath = new PathString("/login"), LoginPath = new PathString("/login"),
CookieName = "TestCookie", CookieName = "TestCookie",
CookieSecure = cookieSecureOption CookieSecure = cookieSecurePolicy
}, SignInAsAlice); }, SignInAsAlice);
var transaction = await SendAsync(server, requestUri); var transaction = await SendAsync(server, requestUri);
@ -231,7 +231,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
CookieName = "TestCookie", CookieName = "TestCookie",
CookiePath = "/foo", CookiePath = "/foo",
CookieDomain = "another.com", CookieDomain = "another.com",
CookieSecure = CookieSecureOption.Always, CookieSecure = CookieSecurePolicy.Always,
CookieHttpOnly = true CookieHttpOnly = true
}, SignInAsAlice, new Uri("http://example.com/base")); }, SignInAsAlice, new Uri("http://example.com/base"));
@ -248,7 +248,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
var server2 = CreateServer(new CookieAuthenticationOptions var server2 = CreateServer(new CookieAuthenticationOptions
{ {
CookieName = "SecondCookie", CookieName = "SecondCookie",
CookieSecure = CookieSecureOption.Never, CookieSecure = CookieSecurePolicy.None,
CookieHttpOnly = false CookieHttpOnly = false
}, SignInAsAlice, new Uri("http://example.com/base")); }, SignInAsAlice, new Uri("http://example.com/base"));

View File

@ -37,18 +37,18 @@ namespace Microsoft.AspNetCore.CookiePolicy.Test
await RunTest("/secureAlways", await RunTest("/secureAlways",
new CookiePolicyOptions new CookiePolicyOptions
{ {
Secure = SecurePolicy.Always Secure = CookieSecurePolicy.Always
}, },
SecureCookieAppends, SecureCookieAppends,
new RequestTest("http://example.com/secureAlways", new RequestTest("http://example.com/secureAlways",
transaction => transaction =>
{ {
Assert.NotNull(transaction.SetCookie); Assert.NotNull(transaction.SetCookie);
Assert.Equal("A=A; path=/; secure", transaction.SetCookie[0]); Assert.Equal("A=A; path=/; secure", transaction.SetCookie[0]);
Assert.Equal("B=B; path=/; secure", transaction.SetCookie[1]); Assert.Equal("B=B; path=/; secure", transaction.SetCookie[1]);
Assert.Equal("C=C; path=/; secure", transaction.SetCookie[2]); Assert.Equal("C=C; path=/; secure", transaction.SetCookie[2]);
Assert.Equal("D=D; path=/; secure", transaction.SetCookie[3]); Assert.Equal("D=D; path=/; secure", transaction.SetCookie[3]);
})); }));
} }
[Fact] [Fact]
@ -57,19 +57,18 @@ namespace Microsoft.AspNetCore.CookiePolicy.Test
await RunTest("/secureNone", await RunTest("/secureNone",
new CookiePolicyOptions new CookiePolicyOptions
{ {
Secure = SecurePolicy.None Secure = CookieSecurePolicy.None
}, },
SecureCookieAppends, SecureCookieAppends,
new RequestTest("http://example.com/secureNone", new RequestTest("http://example.com/secureNone",
transaction => transaction =>
{ {
Assert.NotNull(transaction.SetCookie); Assert.NotNull(transaction.SetCookie);
Assert.NotNull(transaction.SetCookie); Assert.Equal("A=A; path=/", transaction.SetCookie[0]);
Assert.Equal("A=A; path=/", transaction.SetCookie[0]); Assert.Equal("B=B; path=/", transaction.SetCookie[1]);
Assert.Equal("B=B; path=/", transaction.SetCookie[1]); Assert.Equal("C=C; path=/", transaction.SetCookie[2]);
Assert.Equal("C=C; path=/", transaction.SetCookie[2]); Assert.Equal("D=D; path=/; secure", transaction.SetCookie[3]);
Assert.Equal("D=D; path=/; secure", transaction.SetCookie[3]); }));
}));
} }
[Fact] [Fact]
@ -78,27 +77,27 @@ namespace Microsoft.AspNetCore.CookiePolicy.Test
await RunTest("/secureSame", await RunTest("/secureSame",
new CookiePolicyOptions new CookiePolicyOptions
{ {
Secure = SecurePolicy.SameAsRequest Secure = CookieSecurePolicy.SameAsRequest
}, },
SecureCookieAppends, SecureCookieAppends,
new RequestTest("http://example.com/secureSame", new RequestTest("http://example.com/secureSame",
transaction => transaction =>
{ {
Assert.NotNull(transaction.SetCookie); Assert.NotNull(transaction.SetCookie);
Assert.Equal("A=A; path=/", transaction.SetCookie[0]); Assert.Equal("A=A; path=/", transaction.SetCookie[0]);
Assert.Equal("B=B; path=/", transaction.SetCookie[1]); Assert.Equal("B=B; path=/", transaction.SetCookie[1]);
Assert.Equal("C=C; path=/", transaction.SetCookie[2]); Assert.Equal("C=C; path=/", transaction.SetCookie[2]);
Assert.Equal("D=D; path=/", transaction.SetCookie[3]); Assert.Equal("D=D; path=/", transaction.SetCookie[3]);
}), }),
new RequestTest("https://example.com/secureSame", new RequestTest("https://example.com/secureSame",
transaction => transaction =>
{ {
Assert.NotNull(transaction.SetCookie); Assert.NotNull(transaction.SetCookie);
Assert.Equal("A=A; path=/; secure", transaction.SetCookie[0]); Assert.Equal("A=A; path=/; secure", transaction.SetCookie[0]);
Assert.Equal("B=B; path=/; secure", transaction.SetCookie[1]); Assert.Equal("B=B; path=/; secure", transaction.SetCookie[1]);
Assert.Equal("C=C; path=/; secure", transaction.SetCookie[2]); Assert.Equal("C=C; path=/; secure", transaction.SetCookie[2]);
Assert.Equal("D=D; path=/; secure", transaction.SetCookie[3]); Assert.Equal("D=D; path=/; secure", transaction.SetCookie[3]);
})); }));
} }
[Fact] [Fact]
@ -283,13 +282,13 @@ namespace Microsoft.AspNetCore.CookiePolicy.Test
{ {
var builder = new WebHostBuilder() var builder = new WebHostBuilder()
.Configure(app => .Configure(app =>
{
app.Map(path, map =>
{ {
map.UseCookiePolicy(cookiePolicy); app.Map(path, map =>
map.Run(configureSetup); {
map.UseCookiePolicy(cookiePolicy);
map.Run(configureSetup);
});
}); });
});
var server = new TestServer(builder); var server = new TestServer(builder);
foreach (var test in tests) foreach (var test in tests)
{ {