Add CookieBuilder to CookieTempDataProviderOptions and obsolete duplicate API (#6472)
This commit is contained in:
parent
ef43b100a6
commit
1eb7f9e032
|
|
@ -1,6 +1,7 @@
|
||||||
// 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 Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
||||||
|
|
||||||
|
|
@ -11,21 +12,65 @@ namespace Microsoft.AspNetCore.Mvc
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class CookieTempDataProviderOptions
|
public class CookieTempDataProviderOptions
|
||||||
{
|
{
|
||||||
|
private CookieBuilder _cookieBuilder = new CookieBuilder
|
||||||
|
{
|
||||||
|
Name = CookieTempDataProvider.CookieName,
|
||||||
|
HttpOnly = true,
|
||||||
|
SameSite = SameSiteMode.Strict,
|
||||||
|
SecurePolicy = CookieSecurePolicy.SameAsRequest,
|
||||||
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// <para>
|
||||||
|
/// Determines the settings used to create the cookie in <see cref="CookieTempDataProvider"/>.
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
|
/// <see cref="CookieBuilder.SameSite"/> defaults to <see cref="SameSiteMode.Strict"/>.
|
||||||
|
/// <see cref="CookieBuilder.SecurePolicy"/> defaults to <see cref="CookieSecurePolicy.SameAsRequest" />.
|
||||||
|
/// <see cref="CookieBuilder.HttpOnly"/> defaults to <c>true</c>
|
||||||
|
/// </para>
|
||||||
|
/// </summary>
|
||||||
|
public CookieBuilder Cookie
|
||||||
|
{
|
||||||
|
get => _cookieBuilder;
|
||||||
|
set => _cookieBuilder = value ?? throw new ArgumentNullException(nameof(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Obsolete API
|
||||||
|
/// <summary>
|
||||||
|
/// <para>
|
||||||
|
/// This property is obsolete and will be removed in a future version. The recommended alternative is <seealso cref="CookieBuilder.Path"/> on <see cref="Cookie"/>.
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
/// The path set on the cookie. If set to <c>null</c>, the "path" attribute on the cookie is set to the current
|
/// The path set on the cookie. If set to <c>null</c>, the "path" attribute on the cookie is set to the current
|
||||||
/// request's <see cref="HttpRequest.PathBase"/> value. If the value of <see cref="HttpRequest.PathBase"/> is
|
/// request's <see cref="HttpRequest.PathBase"/> value. If the value of <see cref="HttpRequest.PathBase"/> is
|
||||||
/// <c>null</c> or empty, then the "path" attribute is set to the value of <see cref="CookieOptions.Path"/>.
|
/// <c>null</c> or empty, then the "path" attribute is set to the value of <see cref="CookieOptions.Path"/>.
|
||||||
|
/// </para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Path { get; set; }
|
[Obsolete("This property is obsolete and will be removed in a future version. The recommended alternative is " + nameof(Cookie) + "." + nameof(CookieBuilder.Path) + ".")]
|
||||||
|
public string Path { get => Cookie.Path; set => Cookie.Path = value; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// <para>
|
||||||
|
/// This property is obsolete and will be removed in a future version. The recommended alternative is <seealso cref="CookieBuilder.Domain"/> on <see cref="Cookie"/>.
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
/// The domain set on a cookie. Defaults to <c>null</c>.
|
/// The domain set on a cookie. Defaults to <c>null</c>.
|
||||||
|
/// </para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Domain { get; set; }
|
[Obsolete("This property is obsolete and will be removed in a future version. The recommended alternative is " + nameof(Cookie) + "." + nameof(CookieBuilder.Domain) + ".")]
|
||||||
|
public string Domain { get => Cookie.Domain; set => Cookie.Domain = value; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// <para>
|
||||||
|
/// This property is obsolete and will be removed in a future version. The recommended alternative is <seealso cref="CookieBuilder.Name"/> on <see cref="Cookie"/>.
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
/// The name of the cookie which stores TempData. Defaults to <see cref="CookieTempDataProvider.CookieName"/>.
|
/// The name of the cookie which stores TempData. Defaults to <see cref="CookieTempDataProvider.CookieName"/>.
|
||||||
|
/// </para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[Obsolete("This property is obsolete and will be removed in a future version. The recommended alternative is " + nameof(Cookie) + "." + nameof(CookieBuilder.Name) + ".")]
|
||||||
public string CookieName { get; set; } = CookieTempDataProvider.CookieName;
|
public string CookieName { get; set; } = CookieTempDataProvider.CookieName;
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,9 +39,9 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
|
||||||
throw new ArgumentNullException(nameof(context));
|
throw new ArgumentNullException(nameof(context));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context.Request.Cookies.ContainsKey(_options.CookieName))
|
if (context.Request.Cookies.ContainsKey(_options.Cookie.Name))
|
||||||
{
|
{
|
||||||
var encodedValue = _chunkingCookieManager.GetRequestCookie(context, _options.CookieName);
|
var encodedValue = _chunkingCookieManager.GetRequestCookie(context, _options.Cookie.Name);
|
||||||
if (!string.IsNullOrEmpty(encodedValue))
|
if (!string.IsNullOrEmpty(encodedValue))
|
||||||
{
|
{
|
||||||
var protectedData = Base64UrlTextEncoder.Decode(encodedValue);
|
var protectedData = Base64UrlTextEncoder.Decode(encodedValue);
|
||||||
|
|
@ -60,13 +60,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
|
||||||
throw new ArgumentNullException(nameof(context));
|
throw new ArgumentNullException(nameof(context));
|
||||||
}
|
}
|
||||||
|
|
||||||
var cookieOptions = new CookieOptions()
|
var cookieOptions = _options.Cookie.Build(context);
|
||||||
{
|
|
||||||
Domain = string.IsNullOrEmpty(_options.Domain) ? null : _options.Domain,
|
|
||||||
HttpOnly = true,
|
|
||||||
SameSite = SameSiteMode.Strict,
|
|
||||||
Secure = context.Request.IsHttps,
|
|
||||||
};
|
|
||||||
SetCookiePath(context, cookieOptions);
|
SetCookiePath(context, cookieOptions);
|
||||||
|
|
||||||
var hasValues = (values != null && values.Count > 0);
|
var hasValues = (values != null && values.Count > 0);
|
||||||
|
|
@ -75,19 +69,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, _options.CookieName, encodedValue, cookieOptions);
|
_chunkingCookieManager.AppendResponseCookie(context, _options.Cookie.Name, encodedValue, cookieOptions);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_chunkingCookieManager.DeleteCookie(context, _options.CookieName, cookieOptions);
|
_chunkingCookieManager.DeleteCookie(context, _options.Cookie.Name, cookieOptions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetCookiePath(HttpContext httpContext, CookieOptions cookieOptions)
|
private void SetCookiePath(HttpContext httpContext, CookieOptions cookieOptions)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(_options.Path))
|
if (!string.IsNullOrEmpty(_options.Cookie.Path))
|
||||||
{
|
{
|
||||||
cookieOptions.Path = _options.Path;
|
cookieOptions.Path = _options.Cookie.Path;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
|
||||||
public void SaveTempData_UsesCookieName_FromOptions()
|
public void SaveTempData_UsesCookieName_FromOptions()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var exepectedCookieName = "TestCookieName";
|
var expectedCookieName = "TestCookieName";
|
||||||
var values = new Dictionary<string, object>();
|
var values = new Dictionary<string, object>();
|
||||||
values.Add("int", 10);
|
values.Add("int", 10);
|
||||||
|
|
||||||
|
|
@ -30,7 +30,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
|
||||||
var expectedDataInCookie = Base64UrlTextEncoder.Encode(expectedDataToProtect);
|
var expectedDataInCookie = Base64UrlTextEncoder.Encode(expectedDataToProtect);
|
||||||
var tempDataProvider = GetProvider(dataProtector: null, options: new CookieTempDataProviderOptions()
|
var tempDataProvider = GetProvider(dataProtector: null, options: new CookieTempDataProviderOptions()
|
||||||
{
|
{
|
||||||
CookieName = exepectedCookieName
|
Cookie = { Name = expectedCookieName }
|
||||||
});
|
});
|
||||||
|
|
||||||
var responseCookies = new MockResponseCookieCollection();
|
var responseCookies = new MockResponseCookieCollection();
|
||||||
|
|
@ -46,8 +46,8 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
|
||||||
tempDataProvider.SaveTempData(httpContext.Object, values);
|
tempDataProvider.SaveTempData(httpContext.Object, values);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Contains(responseCookies, (cookie) => cookie.Key == exepectedCookieName);
|
Assert.Contains(responseCookies, (cookie) => cookie.Key == expectedCookieName);
|
||||||
var cookieInfo = responseCookies[exepectedCookieName];
|
var cookieInfo = responseCookies[expectedCookieName];
|
||||||
Assert.Equal(expectedDataInCookie, cookieInfo.Value);
|
Assert.Equal(expectedDataInCookie, cookieInfo.Value);
|
||||||
Assert.Equal("/", cookieInfo.Options.Path);
|
Assert.Equal("/", cookieInfo.Options.Path);
|
||||||
}
|
}
|
||||||
|
|
@ -230,7 +230,14 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
|
||||||
var dataProtector = new PassThroughDataProtector();
|
var dataProtector = new PassThroughDataProtector();
|
||||||
var tempDataProvider = GetProvider(
|
var tempDataProvider = GetProvider(
|
||||||
dataProtector,
|
dataProtector,
|
||||||
new CookieTempDataProviderOptions() { Path = optionsPath, Domain = optionsDomain });
|
new CookieTempDataProviderOptions
|
||||||
|
{
|
||||||
|
Cookie =
|
||||||
|
{
|
||||||
|
Path = optionsPath,
|
||||||
|
Domain = optionsDomain
|
||||||
|
}
|
||||||
|
});
|
||||||
var responseCookies = new MockResponseCookieCollection();
|
var responseCookies = new MockResponseCookieCollection();
|
||||||
var httpContext = new Mock<HttpContext>();
|
var httpContext = new Mock<HttpContext>();
|
||||||
httpContext
|
httpContext
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue