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
|
build\Key.snk = build\Key.snk
|
||||||
NuGet.config = NuGet.config
|
NuGet.config = NuGet.config
|
||||||
build\repo.props = build\repo.props
|
build\repo.props = build\repo.props
|
||||||
|
build\sources.props = build\sources.props
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
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}"
|
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;
|
_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()
|
private bool CheckPolicyRequired()
|
||||||
{
|
{
|
||||||
return !CanTrack
|
return !CanTrack
|
||||||
|
|
@ -109,6 +133,14 @@ namespace Microsoft.AspNetCore.CookiePolicy
|
||||||
throw new ArgumentNullException(nameof(options));
|
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;
|
var issueCookie = CanTrack || options.IsEssential;
|
||||||
ApplyPolicy(options);
|
ApplyPolicy(options);
|
||||||
if (Options.OnAppendCookie != null)
|
if (Options.OnAppendCookie != null)
|
||||||
|
|
@ -126,10 +158,7 @@ namespace Microsoft.AspNetCore.CookiePolicy
|
||||||
issueCookie = context.IssueCookie;
|
issueCookie = context.IssueCookie;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (issueCookie)
|
return issueCookie;
|
||||||
{
|
|
||||||
Cookies.Append(key, value, options);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Delete(string key)
|
public void Delete(string key)
|
||||||
|
|
|
||||||
|
|
@ -542,6 +542,91 @@ namespace Microsoft.AspNetCore.CookiePolicy.Test
|
||||||
Assert.Empty(httpContext.Response.Headers[HeaderNames.SetCookie]);
|
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)
|
private Task<HttpContext> RunTestAsync(Action<CookiePolicyOptions> configureOptions, Action<HttpContext> configureRequest, RequestDelegate handleRequest)
|
||||||
{
|
{
|
||||||
var builder = new WebHostBuilder()
|
var builder = new WebHostBuilder()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue