[Fixes #104] Expose cookie options via Antiforgery options

This commit is contained in:
Kiran Challa 2016-10-31 16:43:09 -07:00
parent 72bc9c0f2c
commit 08cb67b7e4
3 changed files with 85 additions and 1 deletions

View File

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.AspNetCore.Http;
namespace Microsoft.AspNetCore.Antiforgery
{
@ -45,6 +46,18 @@ namespace Microsoft.AspNetCore.Antiforgery
}
}
/// <summary>
/// The path set on the cookie. If it's <c>null</c>, the "path" attribute on the cookie is set to current
/// request's <see cref="HttpRequest.PathBase"/> value.
/// </summary>
public PathString? CookiePath { get; set; }
/// <summary>
/// The domain set on the cookie. By default its <c>null</c> which results in the "domain" attribute not being
/// set.
/// </summary>
public string CookieDomain { get; set; }
/// <summary>
/// Specifies the name of the antiforgery token field that is used by the antiforgery system.
/// </summary>

View File

@ -71,7 +71,8 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
var options = new CookieOptions();
options.HttpOnly = true;
options.Path = httpContext.Request.PathBase;
options.Path = _options.CookiePath ?? httpContext.Request.PathBase;
options.Domain = _options.CookieDomain;
// Note: don't use "newCookie.Secure = _options.RequireSSL;" since the default
// value of newCookie.Secure is populated out of band.
if (_options.RequireSsl)

View File

@ -308,6 +308,76 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
Assert.Equal(requestPathBase, cookies.Options.Path);
}
[Fact]
public void SaveCookieToken_NonNullAntiforgeryOptionsCookiePath_UsesOptionsCookiePath()
{
// Arrange
var expectedCookiePath = "/";
var requestPathBase = "/vdir1";
var token = "serialized-value";
var cookies = new MockResponseCookieCollection();
var httpContext = new Mock<HttpContext>();
httpContext
.Setup(hc => hc.Response.Cookies)
.Returns(cookies);
httpContext
.SetupGet(hc => hc.Request.PathBase)
.Returns(requestPathBase);
httpContext
.SetupGet(hc => hc.Request.Path)
.Returns("/index.html");
var options = new AntiforgeryOptions();
options.CookieName = _cookieName;
options.CookiePath = expectedCookiePath;
var tokenStore = new DefaultAntiforgeryTokenStore(new TestOptionsManager(options));
// Act
tokenStore.SaveCookieToken(httpContext.Object, token);
// Assert
Assert.Equal(1, cookies.Count);
Assert.NotNull(cookies);
Assert.Equal(_cookieName, cookies.Key);
Assert.Equal("serialized-value", cookies.Value);
Assert.True(cookies.Options.HttpOnly);
Assert.Equal(expectedCookiePath, cookies.Options.Path);
}
[Fact]
public void SaveCookieToken_NonNullAntiforgeryOptionsCookieDomain_UsesOptionsCookieDomain()
{
// Arrange
var expectedCookieDomain = "microsoft.com";
var token = "serialized-value";
var cookies = new MockResponseCookieCollection();
var httpContext = new Mock<HttpContext>();
httpContext
.Setup(hc => hc.Response.Cookies)
.Returns(cookies);
httpContext
.SetupGet(hc => hc.Request.PathBase)
.Returns("/vdir1");
httpContext
.SetupGet(hc => hc.Request.Path)
.Returns("/index.html");
var options = new AntiforgeryOptions();
options.CookieName = _cookieName;
options.CookieDomain = expectedCookieDomain;
var tokenStore = new DefaultAntiforgeryTokenStore(new TestOptionsManager(options));
// Act
tokenStore.SaveCookieToken(httpContext.Object, token);
// Assert
Assert.Equal(1, cookies.Count);
Assert.NotNull(cookies);
Assert.Equal(_cookieName, cookies.Key);
Assert.Equal("serialized-value", cookies.Value);
Assert.True(cookies.Options.HttpOnly);
Assert.Equal("/vdir1", cookies.Options.Path);
Assert.Equal(expectedCookieDomain, cookies.Options.Domain);
}
private HttpContext GetHttpContext(string cookieName, string cookieValue)
{
var cookies = new RequestCookieCollection(new Dictionary<string, string>