Implement ITrackingConsentFeature.CreateConsentCookie() #1590
This commit is contained in:
parent
da066d50e0
commit
1f855f7b06
|
|
@ -68,6 +68,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
|||
build\Key.snk = build\Key.snk
|
||||
NuGet.config = NuGet.config
|
||||
build\repo.props = build\repo.props
|
||||
build\sources.props = build\sources.props
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Authorization.Policy", "src\Microsoft.AspNetCore.Authorization.Policy\Microsoft.AspNetCore.Authorization.Policy.csproj", "{58194599-F07D-47A3-9DF2-E21A22C5EF9E}"
|
||||
|
|
|
|||
|
|
@ -82,6 +82,30 @@ namespace Microsoft.AspNetCore.CookiePolicy
|
|||
_hasConsent = false;
|
||||
}
|
||||
|
||||
// Note policy will be applied. We don't want to bypass policy because we want HttpOnly, Secure, etc. to apply.
|
||||
public string CreateConsentCookie()
|
||||
{
|
||||
var key = Options.ConsentCookie.Name;
|
||||
var value = ConsentValue;
|
||||
var options = Options.ConsentCookie.Build(Context);
|
||||
ApplyAppendPolicy(ref key, ref value, options);
|
||||
|
||||
var setCookieHeaderValue = new Net.Http.Headers.SetCookieHeaderValue(
|
||||
Uri.EscapeDataString(key),
|
||||
Uri.EscapeDataString(value))
|
||||
{
|
||||
Domain = options.Domain,
|
||||
Path = options.Path,
|
||||
Expires = options.Expires,
|
||||
MaxAge = options.MaxAge,
|
||||
Secure = options.Secure,
|
||||
SameSite = (Net.Http.Headers.SameSiteMode)options.SameSite,
|
||||
HttpOnly = options.HttpOnly
|
||||
};
|
||||
|
||||
return setCookieHeaderValue.ToString();
|
||||
}
|
||||
|
||||
private bool CheckPolicyRequired()
|
||||
{
|
||||
return !CanTrack
|
||||
|
|
@ -109,6 +133,14 @@ namespace Microsoft.AspNetCore.CookiePolicy
|
|||
throw new ArgumentNullException(nameof(options));
|
||||
}
|
||||
|
||||
if (ApplyAppendPolicy(ref key, ref value, options))
|
||||
{
|
||||
Cookies.Append(key, value, options);
|
||||
}
|
||||
}
|
||||
|
||||
private bool ApplyAppendPolicy(ref string key, ref string value, CookieOptions options)
|
||||
{
|
||||
var issueCookie = CanTrack || options.IsEssential;
|
||||
ApplyPolicy(options);
|
||||
if (Options.OnAppendCookie != null)
|
||||
|
|
@ -126,10 +158,7 @@ namespace Microsoft.AspNetCore.CookiePolicy
|
|||
issueCookie = context.IssueCookie;
|
||||
}
|
||||
|
||||
if (issueCookie)
|
||||
{
|
||||
Cookies.Append(key, value, options);
|
||||
}
|
||||
return issueCookie;
|
||||
}
|
||||
|
||||
public void Delete(string key)
|
||||
|
|
|
|||
|
|
@ -542,6 +542,91 @@ namespace Microsoft.AspNetCore.CookiePolicy.Test
|
|||
Assert.Empty(httpContext.Response.Headers[HeaderNames.SetCookie]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CreateConsentCookieMatchesGrantConsentCookie()
|
||||
{
|
||||
var httpContext = await RunTestAsync(options =>
|
||||
{
|
||||
options.CheckConsentNeeded = context => true;
|
||||
},
|
||||
requestContext => { },
|
||||
context =>
|
||||
{
|
||||
var feature = context.Features.Get<ITrackingConsentFeature>();
|
||||
Assert.True(feature.IsConsentNeeded);
|
||||
Assert.False(feature.HasConsent);
|
||||
Assert.False(feature.CanTrack);
|
||||
|
||||
feature.GrantConsent();
|
||||
|
||||
Assert.True(feature.IsConsentNeeded);
|
||||
Assert.True(feature.HasConsent);
|
||||
Assert.True(feature.CanTrack);
|
||||
|
||||
var cookie = feature.CreateConsentCookie();
|
||||
context.Response.Headers["ManualCookie"] = cookie;
|
||||
|
||||
return Task.CompletedTask;
|
||||
});
|
||||
|
||||
var cookies = SetCookieHeaderValue.ParseList(httpContext.Response.Headers[HeaderNames.SetCookie]);
|
||||
Assert.Equal(1, cookies.Count);
|
||||
var consentCookie = cookies[0];
|
||||
Assert.Equal(".AspNet.Consent", consentCookie.Name);
|
||||
Assert.Equal("yes", consentCookie.Value);
|
||||
Assert.Equal(Net.Http.Headers.SameSiteMode.Lax, consentCookie.SameSite);
|
||||
Assert.NotNull(consentCookie.Expires);
|
||||
|
||||
Assert.Equal(httpContext.Response.Headers[HeaderNames.SetCookie], httpContext.Response.Headers["ManualCookie"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CreateConsentCookieAppliesPolicy()
|
||||
{
|
||||
var httpContext = await RunTestAsync(options =>
|
||||
{
|
||||
options.CheckConsentNeeded = context => true;
|
||||
options.MinimumSameSitePolicy = Http.SameSiteMode.Strict;
|
||||
options.OnAppendCookie = context =>
|
||||
{
|
||||
Assert.Equal(".AspNet.Consent", context.CookieName);
|
||||
Assert.Equal("yes", context.CookieValue);
|
||||
Assert.Equal(Http.SameSiteMode.Strict, context.CookieOptions.SameSite);
|
||||
context.CookieName += "1";
|
||||
context.CookieValue += "1";
|
||||
};
|
||||
},
|
||||
requestContext => { },
|
||||
context =>
|
||||
{
|
||||
var feature = context.Features.Get<ITrackingConsentFeature>();
|
||||
Assert.True(feature.IsConsentNeeded);
|
||||
Assert.False(feature.HasConsent);
|
||||
Assert.False(feature.CanTrack);
|
||||
|
||||
feature.GrantConsent();
|
||||
|
||||
Assert.True(feature.IsConsentNeeded);
|
||||
Assert.True(feature.HasConsent);
|
||||
Assert.True(feature.CanTrack);
|
||||
|
||||
var cookie = feature.CreateConsentCookie();
|
||||
context.Response.Headers["ManualCookie"] = cookie;
|
||||
|
||||
return Task.CompletedTask;
|
||||
});
|
||||
|
||||
var cookies = SetCookieHeaderValue.ParseList(httpContext.Response.Headers[HeaderNames.SetCookie]);
|
||||
Assert.Equal(1, cookies.Count);
|
||||
var consentCookie = cookies[0];
|
||||
Assert.Equal(".AspNet.Consent1", consentCookie.Name);
|
||||
Assert.Equal("yes1", consentCookie.Value);
|
||||
Assert.Equal(Net.Http.Headers.SameSiteMode.Strict, consentCookie.SameSite);
|
||||
Assert.NotNull(consentCookie.Expires);
|
||||
|
||||
Assert.Equal(httpContext.Response.Headers[HeaderNames.SetCookie], httpContext.Response.Headers["ManualCookie"]);
|
||||
}
|
||||
|
||||
private Task<HttpContext> RunTestAsync(Action<CookiePolicyOptions> configureOptions, Action<HttpContext> configureRequest, RequestDelegate handleRequest)
|
||||
{
|
||||
var builder = new WebHostBuilder()
|
||||
|
|
|
|||
Loading…
Reference in New Issue