[Fixes #5637] Make CookieName of CookieTempDataProvider configurable

This commit is contained in:
Kiran Challa 2017-01-26 15:20:22 -08:00
parent 03cdd15e5c
commit 17dc23a024
3 changed files with 52 additions and 12 deletions

View File

@ -22,5 +22,10 @@ namespace Microsoft.AspNetCore.Mvc
/// The domain set on a cookie. Defaults to <c>null</c>. /// The domain set on a cookie. Defaults to <c>null</c>.
/// </summary> /// </summary>
public string Domain { get; set; } public string Domain { get; set; }
/// <summary>
/// The name of the cookie which stores TempData. Defaults to <see cref="CookieTempDataProvider.CookieName"/>.
/// </summary>
public string CookieName { get; set; } = CookieTempDataProvider.CookieName;
} }
} }

View File

@ -23,14 +23,14 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
private readonly IDataProtector _dataProtector; private readonly IDataProtector _dataProtector;
private readonly TempDataSerializer _tempDataSerializer; private readonly TempDataSerializer _tempDataSerializer;
private readonly ChunkingCookieManager _chunkingCookieManager; private readonly ChunkingCookieManager _chunkingCookieManager;
private readonly IOptions<CookieTempDataProviderOptions> _options; private readonly CookieTempDataProviderOptions _options;
public CookieTempDataProvider(IDataProtectionProvider dataProtectionProvider, IOptions<CookieTempDataProviderOptions> options) public CookieTempDataProvider(IDataProtectionProvider dataProtectionProvider, IOptions<CookieTempDataProviderOptions> options)
{ {
_dataProtector = dataProtectionProvider.CreateProtector(Purpose); _dataProtector = dataProtectionProvider.CreateProtector(Purpose);
_tempDataSerializer = new TempDataSerializer(); _tempDataSerializer = new TempDataSerializer();
_chunkingCookieManager = new ChunkingCookieManager(); _chunkingCookieManager = new ChunkingCookieManager();
_options = options; _options = options.Value;
} }
public IDictionary<string, object> LoadTempData(HttpContext context) public IDictionary<string, object> LoadTempData(HttpContext context)
@ -40,9 +40,9 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
if (context.Request.Cookies.ContainsKey(CookieName)) if (context.Request.Cookies.ContainsKey(_options.CookieName))
{ {
var encodedValue = _chunkingCookieManager.GetRequestCookie(context, CookieName); var encodedValue = _chunkingCookieManager.GetRequestCookie(context, _options.CookieName);
if (!string.IsNullOrEmpty(encodedValue)) if (!string.IsNullOrEmpty(encodedValue))
{ {
var protectedData = Base64UrlTextEncoder.Decode(encodedValue); var protectedData = Base64UrlTextEncoder.Decode(encodedValue);
@ -63,7 +63,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
var cookieOptions = new CookieOptions() var cookieOptions = new CookieOptions()
{ {
Domain = string.IsNullOrEmpty(_options.Value.Domain) ? null : _options.Value.Domain, Domain = string.IsNullOrEmpty(_options.Domain) ? null : _options.Domain,
HttpOnly = true, HttpOnly = true,
Secure = context.Request.IsHttps, Secure = context.Request.IsHttps,
}; };
@ -75,19 +75,19 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
var bytes = _tempDataSerializer.Serialize(values); var bytes = _tempDataSerializer.Serialize(values);
bytes = _dataProtector.Protect(bytes); bytes = _dataProtector.Protect(bytes);
var encodedValue = Base64UrlTextEncoder.Encode(bytes); var encodedValue = Base64UrlTextEncoder.Encode(bytes);
_chunkingCookieManager.AppendResponseCookie(context, CookieName, encodedValue, cookieOptions); _chunkingCookieManager.AppendResponseCookie(context, _options.CookieName, encodedValue, cookieOptions);
} }
else else
{ {
_chunkingCookieManager.DeleteCookie(context, CookieName, cookieOptions); _chunkingCookieManager.DeleteCookie(context, _options.CookieName, cookieOptions);
} }
} }
private void SetCookiePath(HttpContext httpContext, CookieOptions cookieOptions) private void SetCookiePath(HttpContext httpContext, CookieOptions cookieOptions)
{ {
if (!string.IsNullOrEmpty(_options.Value.Path)) if (!string.IsNullOrEmpty(_options.Path))
{ {
cookieOptions.Path = _options.Value.Path; cookieOptions.Path = _options.Path;
} }
else else
{ {

View File

@ -6,9 +6,9 @@ using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.AspNetCore.Http.Internal; using Microsoft.AspNetCore.Http.Internal;
using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal; using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Moq; using Moq;
using Xunit; using Xunit;
@ -17,6 +17,41 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
{ {
public class CookieTempDataProviderTest public class CookieTempDataProviderTest
{ {
[Fact]
public void SaveTempData_UsesCookieName_FromOptions()
{
// Arrange
var exepectedCookieName = "TestCookieName";
var values = new Dictionary<string, object>();
values.Add("int", 10);
var tempDataProviderStore = new TempDataSerializer();
var expectedDataToProtect = tempDataProviderStore.Serialize(values);
var expectedDataInCookie = Base64UrlTextEncoder.Encode(expectedDataToProtect);
var tempDataProvider = GetProvider(dataProtector: null, options: new CookieTempDataProviderOptions()
{
CookieName = exepectedCookieName
});
var responseCookies = new MockResponseCookieCollection();
var httpContext = new Mock<HttpContext>();
httpContext
.SetupGet(hc => hc.Request.PathBase)
.Returns("/");
httpContext
.Setup(hc => hc.Response.Cookies)
.Returns(responseCookies);
// Act
tempDataProvider.SaveTempData(httpContext.Object, values);
// Assert
Assert.Contains(responseCookies, (cookie) => cookie.Key == exepectedCookieName);
var cookieInfo = responseCookies[exepectedCookieName];
Assert.Equal(expectedDataInCookie, cookieInfo.Value);
Assert.Equal("/", cookieInfo.Options.Path);
}
[Fact] [Fact]
public void LoadTempData_ReturnsEmptyDictionary_WhenNoCookieDataIsAvailable() public void LoadTempData_ReturnsEmptyDictionary_WhenNoCookieDataIsAvailable()
{ {
@ -583,11 +618,11 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
private CookieTempDataProvider GetProvider(IDataProtector dataProtector = null, CookieTempDataProviderOptions options = null) private CookieTempDataProvider GetProvider(IDataProtector dataProtector = null, CookieTempDataProviderOptions options = null)
{ {
if(dataProtector == null) if (dataProtector == null)
{ {
dataProtector = new PassThroughDataProtector(); dataProtector = new PassThroughDataProtector();
} }
if(options == null) if (options == null)
{ {
options = new CookieTempDataProviderOptions(); options = new CookieTempDataProviderOptions();
} }