Fixes CookieTempDataProvider to set the secure attribute of a cookie only if a request is secure
This commit is contained in:
parent
a3c06b00cc
commit
07a2f1de06
|
|
@ -68,7 +68,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
|
||||||
Path = string.IsNullOrEmpty(_options.Value.Path) ? GetPathBase(context) : _options.Value.Path,
|
Path = string.IsNullOrEmpty(_options.Value.Path) ? GetPathBase(context) : _options.Value.Path,
|
||||||
Domain = string.IsNullOrEmpty(_options.Value.Domain) ? null : _options.Value.Domain,
|
Domain = string.IsNullOrEmpty(_options.Value.Domain) ? null : _options.Value.Domain,
|
||||||
HttpOnly = true,
|
HttpOnly = true,
|
||||||
Secure = true
|
Secure = context.Request.IsHttps,
|
||||||
};
|
};
|
||||||
|
|
||||||
var hasValues = (values != null && values.Count > 0);
|
var hasValues = (values != null && values.Count > 0);
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
||||||
Assert.NotNull(cookieTempDataProviderCookie.Value);
|
Assert.NotNull(cookieTempDataProviderCookie.Value);
|
||||||
Assert.Equal("/", cookieTempDataProviderCookie.Path);
|
Assert.Equal("/", cookieTempDataProviderCookie.Path);
|
||||||
Assert.Null(cookieTempDataProviderCookie.Domain);
|
Assert.Null(cookieTempDataProviderCookie.Domain);
|
||||||
Assert.True(cookieTempDataProviderCookie.Secure);
|
Assert.False(cookieTempDataProviderCookie.Secure);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Act 2
|
// Act 2
|
||||||
|
|
@ -107,7 +107,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
||||||
Assert.NotNull(setCookieHeader);
|
Assert.NotNull(setCookieHeader);
|
||||||
Assert.Equal("/", setCookieHeader.Path);
|
Assert.Equal("/", setCookieHeader.Path);
|
||||||
Assert.Null(setCookieHeader.Domain);
|
Assert.Null(setCookieHeader.Domain);
|
||||||
Assert.True(setCookieHeader.Secure);
|
Assert.False(setCookieHeader.Secure);
|
||||||
Assert.Null(setCookieHeader.Expires);
|
Assert.Null(setCookieHeader.Expires);
|
||||||
|
|
||||||
// Act 2
|
// Act 2
|
||||||
|
|
@ -134,5 +134,35 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
||||||
Assert.NotNull(setCookieHeader.Expires);
|
Assert.NotNull(setCookieHeader.Expires);
|
||||||
Assert.True(setCookieHeader.Expires < DateTimeOffset.Now); // expired cookie
|
Assert.True(setCookieHeader.Expires < DateTimeOffset.Now); // expired cookie
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(true)]
|
||||||
|
[InlineData(false)]
|
||||||
|
public async Task CookieTempDataProviderCookie_SetsSecureAttributeOnCookie_OnlyIfRequestIsSecure(bool secureRequest)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var protocol = secureRequest ? "https" : "http";
|
||||||
|
var nameValueCollection = new List<KeyValuePair<string, string>>
|
||||||
|
{
|
||||||
|
new KeyValuePair<string, string>("value", "Foo"),
|
||||||
|
};
|
||||||
|
var content = new FormUrlEncodedContent(nameValueCollection);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var response = await Client.PostAsync($"{protocol}://localhost/TempData/SetTempData", content);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
IEnumerable<string> setCookieValues;
|
||||||
|
Assert.True(response.Headers.TryGetValues(HeaderNames.SetCookie, out setCookieValues));
|
||||||
|
var setCookieHeader = setCookieValues
|
||||||
|
.Select(setCookieValue => SetCookieHeaderValue.Parse(setCookieValue))
|
||||||
|
.FirstOrDefault(setCookieHeaderValue => setCookieHeaderValue.Name == CookieTempDataProvider.CookieName);
|
||||||
|
Assert.NotNull(setCookieHeader);
|
||||||
|
Assert.Equal("/", setCookieHeader.Path);
|
||||||
|
Assert.Null(setCookieHeader.Domain);
|
||||||
|
Assert.Equal(secureRequest, setCookieHeader.Secure);
|
||||||
|
Assert.Null(setCookieHeader.Expires);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -90,6 +90,47 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
|
||||||
Assert.Equal(expectedDataToProtect, dataProtector.PlainTextToProtect);
|
Assert.Equal(expectedDataToProtect, dataProtector.PlainTextToProtect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(true)]
|
||||||
|
[InlineData(false)]
|
||||||
|
public void SaveTempData_SetsSecureAttributeOnCookie_OnlyIfRequestIsSecure(bool isSecure)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
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 dataProtector = new PassThroughDataProtector();
|
||||||
|
var tempDataProvider = GetProvider(dataProtector);
|
||||||
|
var responseCookies = new MockResponseCookieCollection();
|
||||||
|
var httpContext = new Mock<HttpContext>();
|
||||||
|
httpContext
|
||||||
|
.SetupGet(hc => hc.Request.PathBase)
|
||||||
|
.Returns("/");
|
||||||
|
httpContext
|
||||||
|
.SetupGet(hc => hc.Request.IsHttps)
|
||||||
|
.Returns(isSecure);
|
||||||
|
httpContext
|
||||||
|
.Setup(hc => hc.Response.Cookies)
|
||||||
|
.Returns(responseCookies);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
tempDataProvider.SaveTempData(httpContext.Object, values);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(1, responseCookies.Count);
|
||||||
|
var cookieInfo = responseCookies[CookieTempDataProvider.CookieName];
|
||||||
|
Assert.NotNull(cookieInfo);
|
||||||
|
Assert.Equal(expectedDataInCookie, cookieInfo.Value);
|
||||||
|
Assert.Equal(expectedDataToProtect, dataProtector.PlainTextToProtect);
|
||||||
|
Assert.Equal("/", cookieInfo.Options.Path);
|
||||||
|
Assert.Equal(isSecure, cookieInfo.Options.Secure);
|
||||||
|
Assert.True(cookieInfo.Options.HttpOnly);
|
||||||
|
Assert.Null(cookieInfo.Options.Expires);
|
||||||
|
Assert.Null(cookieInfo.Options.Domain);
|
||||||
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData(null, "/")]
|
[InlineData(null, "/")]
|
||||||
[InlineData("", "/")]
|
[InlineData("", "/")]
|
||||||
|
|
@ -112,6 +153,9 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
|
||||||
httpContext
|
httpContext
|
||||||
.SetupGet(hc => hc.Request.PathBase)
|
.SetupGet(hc => hc.Request.PathBase)
|
||||||
.Returns(pathBase);
|
.Returns(pathBase);
|
||||||
|
httpContext
|
||||||
|
.SetupGet(hc => hc.Request.IsHttps)
|
||||||
|
.Returns(false);
|
||||||
httpContext
|
httpContext
|
||||||
.Setup(hc => hc.Response.Cookies)
|
.Setup(hc => hc.Response.Cookies)
|
||||||
.Returns(responseCookies);
|
.Returns(responseCookies);
|
||||||
|
|
@ -126,7 +170,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
|
||||||
Assert.Equal(expectedDataInCookie, cookieInfo.Value);
|
Assert.Equal(expectedDataInCookie, cookieInfo.Value);
|
||||||
Assert.Equal(expectedDataToProtect, dataProtector.PlainTextToProtect);
|
Assert.Equal(expectedDataToProtect, dataProtector.PlainTextToProtect);
|
||||||
Assert.Equal(expectedCookiePath, cookieInfo.Options.Path);
|
Assert.Equal(expectedCookiePath, cookieInfo.Options.Path);
|
||||||
Assert.True(cookieInfo.Options.Secure);
|
Assert.False(cookieInfo.Options.Secure);
|
||||||
Assert.True(cookieInfo.Options.HttpOnly);
|
Assert.True(cookieInfo.Options.HttpOnly);
|
||||||
Assert.Null(cookieInfo.Options.Expires);
|
Assert.Null(cookieInfo.Options.Expires);
|
||||||
Assert.Null(cookieInfo.Options.Domain);
|
Assert.Null(cookieInfo.Options.Domain);
|
||||||
|
|
@ -154,6 +198,9 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
|
||||||
new CookieTempDataProviderOptions() { Path = optionsPath, Domain = optionsDomain });
|
new CookieTempDataProviderOptions() { Path = optionsPath, Domain = optionsDomain });
|
||||||
var responseCookies = new MockResponseCookieCollection();
|
var responseCookies = new MockResponseCookieCollection();
|
||||||
var httpContext = new Mock<HttpContext>();
|
var httpContext = new Mock<HttpContext>();
|
||||||
|
httpContext
|
||||||
|
.SetupGet(hc => hc.Request.IsHttps)
|
||||||
|
.Returns(false);
|
||||||
httpContext
|
httpContext
|
||||||
.SetupGet(hc => hc.Request.PathBase)
|
.SetupGet(hc => hc.Request.PathBase)
|
||||||
.Returns(requestPathBase);
|
.Returns(requestPathBase);
|
||||||
|
|
@ -172,7 +219,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
|
||||||
Assert.Equal(expectedDataToProtect, dataProtector.PlainTextToProtect);
|
Assert.Equal(expectedDataToProtect, dataProtector.PlainTextToProtect);
|
||||||
Assert.Equal(expectedCookiePath, cookieInfo.Options.Path);
|
Assert.Equal(expectedCookiePath, cookieInfo.Options.Path);
|
||||||
Assert.Equal(expectedDomain, cookieInfo.Options.Domain);
|
Assert.Equal(expectedDomain, cookieInfo.Options.Domain);
|
||||||
Assert.True(cookieInfo.Options.Secure);
|
Assert.False(cookieInfo.Options.Secure);
|
||||||
Assert.True(cookieInfo.Options.HttpOnly);
|
Assert.True(cookieInfo.Options.HttpOnly);
|
||||||
Assert.Null(cookieInfo.Options.Expires);
|
Assert.Null(cookieInfo.Options.Expires);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue