在 ASP.NET Core 欧洲常规数据保护法规 (GDPR) 支持EU General Data Protection Regulation (GDPR) support in ASP.NET Core
本文内容
ASP.NET Core 提供了 Api 和模板来帮助满足某些欧盟一般数据保护条例(GDPR)要求:
- 项目模板包括扩展点和用作存根标记,你可以将其替换为你的隐私和 cookie 使用策略。
- Pages/私密. cshtml页面或Views/Home/私密视图提供了一个页面,用于详细描述您的站点的隐私策略。
若要启用默认的 cookie 许可功能,如在 ASP.NET Core 3.0 模板生成的应用中的 ASP.NET Core 2.2 模板中找到的功能:
将
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文件添加到项目:
@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 许可功能。
- 项目模板包括扩展点和用作存根标记,你可以将其替换为你的隐私和 cookie 使用策略。
- 使用 cookie 同意功能,你可以要求你提供(并跟踪)用户同意以存储个人信息。如果用户未同意数据收集,并且应用已将CheckConsentNeeded设置为
true
,则不会将不重要的 cookie 发送到浏览器。 - Cookie 可以标记为必要。即使用户尚未同意并禁用跟踪,也会将重要 cookie 发送到浏览器。
- 禁用跟踪后,TempData 和会话 cookie不起作用。
- "标识管理" 页提供了一个链接,用于下载和删除用户数据。
该示例应用允许你测试添加到 ASP.NET Core 2.1 模板的大多数 GDPR 扩展点和 api。有关测试说明,请参阅自述文件。
模板生成的代码中的 ASP.NET Core GDPR 支持ASP.NET Core GDPR support in template-generated code
用项目模板创建 Razor Pages 和 MVC 项目包含以下 GDPR 支持:
- CookiePolicyOptions和UseCookiePolicy在
Startup
类中设置。 - _CookieConsentPartial分部视图。此文件中包括 "接受" 按钮。用户单击 "接受" 按钮时,会提供许可来存储 cookie。
- Pages/私密. cshtml页面或Views/Home/私密视图提供了一个页面,用于详细描述您的站点的隐私策略。_CookieConsentPartial文件生成指向隐私页面的链接。
- 对于通过单独用户帐户创建的应用,"管理" 页提供了下载和删除个人用户数据的链接。
CookiePolicyOptions 和 UseCookiePolicyCookiePolicyOptions and 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();
}
}
Startup.Configure
中调用UseCookiePolicy :
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 分部视图_CookieConsentPartial.cshtml partial view
_CookieConsentPartial分部视图:
@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 许可面板将固定在 _布局 cshtml文件创建的导航栏的顶部。
- 提供 HTML
<p>
元素,用于汇总隐私和 cookie 使用策略。 - 提供指向隐私页面或视图的链接,您可以在其中详细说明网站的隐私策略。
重要 cookieEssential cookies
如果尚未提供存储 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 provider and session state cookies aren't essential
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;
});
个人数据Personal data
ASP.NET Core 通过单独用户帐户创建的应用包括下载和删除个人数据的代码。
选择用户名,然后选择 "个人数据":
说明:
- 若要生成
Account/Manage
代码,请参阅基架标识。 - "删除" 和 "下载" 链接仅作用于默认标识数据。必须扩展用于创建自定义用户数据的应用,以删除/下载自定义用户数据。有关详细信息,请参阅向标识添加、下载和删除自定义用户数据。
- 对于存储在标识数据库表中的用户,保存的令牌
AspNetUserTokens
将在通过外键导致的级联删除行为删除用户时删除。 - 外部提供程序身份验证(如 Facebook 和 Google)在接受 cookie 策略之前不可用。
静态加密Encryption at rest
某些数据库和存储机制允许静态加密。静态加密:
- 自动加密存储的数据。
- 对于访问数据的软件,不对其进行配置、编程或其他操作。
- 是最简单且最安全的选项。
- 允许数据库管理密钥和加密。
例如:
- Microsoft SQL 和 Azure SQL 提供透明数据加密(TDE)。
- 默认情况下,SQL Azure 加密数据库
- 默认情况下,加密 Azure blob、文件、表和队列存储。
对于不提供静态内置加密的数据库,您可以使用磁盘加密来提供相同的保护。例如: