ASP.NET Core 中的欧盟一般数据保护条例 (GDPR) 支持
ASP.NET Core 提供 API 和模板,帮助满足欧盟一般数据保护条例 (GDPR) 的部分要求:
- 项目模板包括扩展点和存根标记,可以将其替换为 privacy 和 cookie 使用策略。
Pages/Privacy.cshtml
页面或Views/Home/Privacy.cshtml
视图提供页面以详细说明站点的 privacy 策略。
若要启用如在生成了应用的当前 ASP.NET Core 模板中的 ASP.NET Core 2.2 模板中发现的默认 cookie 内容,请将以下突出显示的代码添加到 Program.cs
:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential
// cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
在前面的代码中,使用的是 CookiePolicyOptions 和 UseCookiePolicy。
将 cookie 同意部分添加到
_Layout.cshtml
文件:@*Previous markup removed for brevity*@ </header> <div class="container"> <partial name="_CookieConsentPartial" /> <main role="main" class="pb-3"> @RenderBody() </main> </div> <footer class="border-top footer text-muted"> <div class="container"> © 2022 - WebGDPR - <a asp-area="" asp-page="/Privacy">Privacy</a> </div> </footer> <script src="~/lib/jquery/dist/jquery.min.js"></script> <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script> <script src="~/js/site.js" asp-append-version="true"></script> @await RenderSectionAsync("Scripts", required: false) </body> </html>
将
_CookieConsentPartial.cshtml
文件添加项目:@using Microsoft.AspNetCore.Http.Features @{ var consentFeature = Context.Features.Get<ITrackingConsentFeature>(); var showBanner = !consentFeature?.CanTrack ?? false; var cookieString = consentFeature?.CreateConsentCookie(); } @if (showBanner) { <div id="cookieConsent" class="alert alert-info alert-dismissible fade show" role="alert"> Use this space to summarize your privacy and cookie use policy. <a asp-page="/Privacy">Learn More</a>. <button type="button" class="accept-policy close" data-bs-dismiss="alert" aria-label="Close" data-cookie-string="@cookieString"> <span aria-hidden="true">Accept</span> </button> </div> <script> (function () { var button = document.querySelector("#cookieConsent button[data-cookie-string]"); button.addEventListener("click", function (event) { document.cookie = button.dataset.cookieString; }, false); })(); </script> }
选择本文的 ASP.NET Core 2.2 版本,了解 cookie 同意功能。
自定义 cookie 同意值
使用属性“CookiePolicyOptions.ConsentCookieValue
”指定用于跟踪用户是否已同意 cookie 使用策略的值:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
options.ConsentCookieValue = "true";
});
var app = builder.Build();
rest 加密
某些数据库和存储机制允许进行 rest 加密。 rest 加密:
- 自动加密存储的数据。
- 无需对访问数据的软件进行配置、编程或其他操作即可进行加密。
- 最简单且最安全的选项。
- 允许数据库管理密钥和加密。
例如:
- Microsoft SQL 和 Azure SQL 提供透明数据加密 (TDE)。
- SQL Azure 默认加密数据库
- 默认加密 Azure Blob、文件、表和队列存储。
对于不提供内置 rest 加密的数据库,可以使用磁盘加密来提供相同的保护。 例如:
其他资源
- 项目模板包括扩展点和存根标记,可以将其替换为 privacy 和 cookie 使用策略。
- cookie 同意功能允许你请求(和跟踪)用户同意存储个人信息。 如果用户不同意数据收集且应用将 CheckConsentNeeded 设置为
true
,则不会将非必要的 Cookie 发送到浏览器。 - Cookie 可以标记为“必要”。 即使用户未同意且已禁用跟踪,也会将必需的 Cookie 发送到浏览器。
- 禁用跟踪后,TempData 和会话 Cookie 将不起作用。
- Identity 页面提供下载和删除用户数据的链接。
示例应用允许测试已添加到 ASP.NET Core 2.1 模板中的大多数 GDPR 扩展点和 API。 有关测试说明,请参阅 ReadMe 文件。
模板生成代码中的 ASP.NET Core GDPR 支持
使用项目模板创建的 Razor Pages 和 MVC 项目包括以下 GDPR 支持:
- CookiePolicyOptions 和 UseCookiePolicy 在
Startup
类中设置。 - _CookieConsentPartial.cshtml 分部视图。 此文件中包含“接受”按钮。 用户单击“接受”按钮时,即表示同意存储 Cookie。
Pages/Privacy.cshtml
页面或Views/Home/Privacy.cshtml
视图提供页面以详细说明站点的 privacy 策略。 _CookieConsentPartial.cshtml 文件生成指向 Privacy 页的链接。- 对于使用个人用户帐户创建的应用,“管理”页面提供了下载和删除个人用户数据的链接。
CookiePolicyOptions 和 UseCookiePolicy
CookiePolicyOptions 在 Startup.ConfigureServices
中初始化:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services
// to the container.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies
// is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<IdentityUser>()
.AddEntityFrameworkStores<ApplicationDbContext>();
// If the app uses session state, call AddSession.
// services.AddSession();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
// This method gets called by the runtime. Use this method to configure the
// HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseAuthentication();
// If the app uses session state, call Session Middleware after Cookie
// Policy Middleware and before MVC Middleware.
// app.UseSession();
app.UseMvc();
}
}
UseCookiePolicy 在 Startup.Configure
中调用:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services
// to the container.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies
// is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<IdentityUser>()
.AddEntityFrameworkStores<ApplicationDbContext>();
// If the app uses session state, call AddSession.
// services.AddSession();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
// This method gets called by the runtime. Use this method to configure the
// HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseAuthentication();
// If the app uses session state, call Session Middleware after Cookie
// Policy Middleware and before MVC Middleware.
// app.UseSession();
app.UseMvc();
}
}
_CookieConsentPartial.cshtml 分部视图
_CookieConsentPartial.cshtml 分部视图:
@using Microsoft.AspNetCore.Http.Features
@{
var consentFeature = Context.Features.Get<ITrackingConsentFeature>();
var showBanner = !consentFeature?.CanTrack ?? false;
var cookieString = consentFeature?.CreateConsentCookie();
}
@if (showBanner)
{
<nav id="cookieConsent" class="navbar navbar-default navbar-fixed-top" role="alert">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#cookieConsent .navbar-collapse">
<span class="sr-only">Toggle cookie consent banner</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<span class="navbar-brand"><span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span></span>
</div>
<div class="collapse navbar-collapse">
<p class="navbar-text">
Use this space to summarize your privacy and cookie use policy.
</p>
<div class="navbar-right">
<a asp-page="/Privacy" class="btn btn-info navbar-btn">Learn More</a>
<button type="button" class="btn btn-default navbar-btn" data-cookie-string="@cookieString">Accept</button>
</div>
</div>
</div>
</nav>
<script>
(function () {
document.querySelector("#cookieConsent button[data-cookie-string]").addEventListener("click", function (el) {
document.cookie = el.target.dataset.cookieString;
document.querySelector("#cookieConsent").classList.add("hidden");
}, false);
})();
</script>
}
此分部视图:
- 获取用户的跟踪状态。 如果应用配置为需要同意,则用户必须同意才能跟踪 Cookie。 如果需要同意,则 cookie 同意面板固定在由 _Layout.cshtml 文件创建的导航栏的顶部。
- 提供 HTML
<p>
元素,以汇总 privacy 和 cookie 使用策略。 - 提供指向 Privacy 页面或视图的链接,可以在其中详细说明站点的 privacy 策略。
必需的 Cookie
如果未同意存储 Cookie,则仅将标记为必需的 Cookie 发送到浏览器。 以下代码可将 cookie 设置为必需:
public IActionResult OnPostCreateEssentialAsync()
{
HttpContext.Response.Cookies.Append(Constants.EssentialSec,
DateTime.Now.Second.ToString(),
new CookieOptions() { IsEssential = true });
ResponseCookies = Response.Headers[HeaderNames.SetCookie].ToString();
return RedirectToPage("./Index");
}
TempData 提供程序和会话状态 Cookie 不是必需的
TempData 提供程序cookie 不是必需的。 如果禁用跟踪,则 TempData 提供程序不起作用。 若要在禁用跟踪时启用 TempData 提供程序,请在 Startup.ConfigureServices
中将 TempData cookie 标记为必需:
// The TempData provider cookie is not essential. Make it essential
// so TempData is functional when tracking is disabled.
services.Configure<CookieTempDataProviderOptions>(options => {
options.Cookie.IsEssential = true;
});
会话状态 Cookie 不是必需的。 禁用跟踪后,会话状态不起作用。 以下代码可将会话 Cookie 设置为必需:
services.AddSession(options =>
{
options.Cookie.IsEssential = true;
});
个人数据
使用个人用户帐户创建的 ASP.NET Core 应用包含用于下载和删除个人数据的代码。
选择用户名,然后选择“个人数据”:
注意:
- 请参阅基架 Identity,了解如何生成
Account/Manage
代码。 - “删除”和“下载”链接仅对默认 identity 数据起作用。 创建自定义用户数据的应用必须扩展为删除/下载自定义用户数据。 有关详细信息,请参阅添加、下载和删除自定义用户数据到 Identity。
- 通过因外键引起的级联删除行为删除用户时,为用户存储在 Identity 数据库表
AspNetUserTokens
中的已保存令牌将被删除。 - 在接受 cookie 策略之前,Facebook 和 Google 等外部提供程序身份验证不可用。
rest 加密
某些数据库和存储机制允许进行 rest 加密。 rest 加密:
- 自动加密存储的数据。
- 无需对访问数据的软件进行配置、编程或其他操作即可进行加密。
- 最简单且最安全的选项。
- 允许数据库管理密钥和加密。
例如:
- Microsoft SQL 和 Azure SQL 提供透明数据加密 (TDE)。
- SQL Azure 默认加密数据库
- 默认加密 Azure Blob、文件、表和队列存储。
对于不提供内置 rest 加密的数据库,可以使用磁盘加密来提供相同的保护。 例如:
其他资源
- 项目模板包括扩展点和存根标记,可以将其替换为 privacy 和 cookie 使用策略。
Pages/Privacy.cshtml
页面或Views/Home/Privacy.cshtml
视图提供页面以详细说明站点的 privacy 策略。
若要在 ASP.NET Core 模板生成的应用中启用与当前 ASP.NET Core 2.2 模板中的默认 cookie 同意功能类似的功能,请执行以下操作:
将
using Microsoft.AspNetCore.Http
添加到 using 指令列表中。将 CookiePolicyOptions 添加到
Startup.ConfigureServices
,UseCookiePolicy 添加到Startup.Configure
:public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } public void ConfigureServices(IServiceCollection services) { services.Configure<CookiePolicyOptions>(options => { // This lambda determines whether user consent for non-essential // cookies is needed for a given request. options.CheckConsentNeeded = context => true; // requires using Microsoft.AspNetCore.Http; options.MinimumSameSitePolicy = SameSiteMode.None; }); services.AddRazorPages(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseCookiePolicy(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapRazorPages(); }); } }
将 cookie 同意部分添加到
_Layout.cshtml
文件:@*Previous markup removed for brevity*@ </header> <div class="container"> <partial name="_CookieConsentPartial" /> <main role="main" class="pb-3"> @RenderBody() </main> </div> <footer class="border-top footer text-muted"> <div class="container"> © 2019 - RPCC - <a asp-area="" asp-page="/Privacy">Privacy</a> </div> </footer> <script src="~/lib/jquery/dist/jquery.js"></script> <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.js"></script> <script src="~/js/site.js" asp-append-version="true"></script> @RenderSection("Scripts", required: false) </body> </html>
将 _CookieConsentPartial.cshtml 文件添加到项目:
@using Microsoft.AspNetCore.Http.Features @{ var consentFeature = Context.Features.Get<ITrackingConsentFeature>(); var showBanner = !consentFeature?.CanTrack ?? false; var cookieString = consentFeature?.CreateConsentCookie(); } @if (showBanner) { <div id="cookieConsent" class="alert alert-info alert-dismissible fade show" role="alert"> Use this space to summarize your privacy and cookie use policy. <a asp-page="/Privacy">Learn More</a>. <button type="button" class="accept-policy close" data-dismiss="alert" aria-label="Close" data-cookie-string="@cookieString"> <span aria-hidden="true">Accept</span> </button> </div> <script> (function () { var button = document.querySelector("#cookieConsent button[data-cookie-string]"); button.addEventListener("click", function (event) { document.cookie = button.dataset.cookieString; }, false); })(); </script> }
选择本文的 ASP.NET Core 2.2 版本,了解 cookie 同意功能。
- 项目模板包括扩展点和存根标记,可以将其替换为 privacy 和 cookie 使用策略。
Pages/Privacy.cshtml
页面或Views/Home/Privacy.cshtml
视图提供页面以详细说明站点的 privacy 策略。
若要启用如在生成了应用的当前 ASP.NET Core 模板中的 ASP.NET Core 2.2 模板中发现的默认 cookie 内容,请将以下突出显示的代码添加到 Program.cs
:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential
// cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
在前面的代码中,使用的是 CookiePolicyOptions 和 UseCookiePolicy。
将 cookie 同意部分添加到
_Layout.cshtml
文件:@*Previous markup removed for brevity*@ </header> <div class="container"> <partial name="_CookieConsentPartial" /> <main role="main" class="pb-3"> @RenderBody() </main> </div> <footer class="border-top footer text-muted"> <div class="container"> © 2022 - WebGDPR - <a asp-area="" asp-page="/Privacy">Privacy</a> </div> </footer> <script src="~/lib/jquery/dist/jquery.min.js"></script> <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script> <script src="~/js/site.js" asp-append-version="true"></script> @await RenderSectionAsync("Scripts", required: false) </body> </html>
将
_CookieConsentPartial.cshtml
文件添加项目:@using Microsoft.AspNetCore.Http.Features @{ var consentFeature = Context.Features.Get<ITrackingConsentFeature>(); var showBanner = !consentFeature?.CanTrack ?? false; var cookieString = consentFeature?.CreateConsentCookie(); } @if (showBanner) { <div id="cookieConsent" class="alert alert-info alert-dismissible fade show" role="alert"> Use this space to summarize your privacy and cookie use policy. <a asp-page="/Privacy">Learn More</a>. <button type="button" class="accept-policy close" data-bs-dismiss="alert" aria-label="Close" data-cookie-string="@cookieString"> <span aria-hidden="true">Accept</span> </button> </div> <script> (function () { var button = document.querySelector("#cookieConsent button[data-cookie-string]"); button.addEventListener("click", function (event) { document.cookie = button.dataset.cookieString; }, false); })(); </script> }
选择本文的 ASP.NET Core 2.2 版本,了解 cookie 同意功能。
rest 加密
某些数据库和存储机制允许进行 rest 加密。 rest 加密:
- 自动加密存储的数据。
- 无需对访问数据的软件进行配置、编程或其他操作即可进行加密。
- 最简单且最安全的选项。
- 允许数据库管理密钥和加密。
例如:
- Microsoft SQL 和 Azure SQL 提供透明数据加密 (TDE)。
- SQL Azure 默认加密数据库
- 默认加密 Azure Blob、文件、表和队列存储。
对于不提供内置 rest 加密的数据库,可以使用磁盘加密来提供相同的保护。 例如: