在 ASP.NET Core 欧洲常规数据保护法规 (GDPR) 支持EU General Data Protection Regulation (GDPR) support in ASP.NET Core

本文内容

作者:Rick Anderson

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

  1. public class Startup
  2. {
  3. public Startup(IConfiguration configuration)
  4. {
  5. Configuration = configuration;
  6. }
  7. public IConfiguration Configuration { get; }
  8. public void ConfigureServices(IServiceCollection services)
  9. {
  10. services.Configure<CookiePolicyOptions>(options =>
  11. {
  12. // This lambda determines whether user consent for non-essential
  13. // cookies is needed for a given request.
  14. options.CheckConsentNeeded = context => true;
  15. // requires using Microsoft.AspNetCore.Http;
  16. options.MinimumSameSitePolicy = SameSiteMode.None;
  17. });
  18. services.AddRazorPages();
  19. }
  20. public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
  21. {
  22. if (env.IsDevelopment())
  23. {
  24. app.UseDeveloperExceptionPage();
  25. }
  26. else
  27. {
  28. app.UseExceptionHandler("/Error");
  29. app.UseHsts();
  30. }
  31. app.UseHttpsRedirection();
  32. app.UseStaticFiles();
  33. app.UseCookiePolicy();
  34. app.UseRouting();
  35. app.UseAuthorization();
  36. app.UseEndpoints(endpoints =>
  37. {
  38. endpoints.MapRazorPages();
  39. });
  40. }
  41. }
  • 将 cookie 同意部分添加到 _Layout 的 cshtml文件中:
  1. @*Previous markup removed for brevity*@
  2. </header>
  3. <div class="container">
  4. <partial name="_CookieConsentPartial" />
  5. <main role="main" class="pb-3">
  6. @RenderBody()
  7. </main>
  8. </div>
  9. <footer class="border-top footer text-muted">
  10. <div class="container">
  11. &copy; 2019 - RPCC - <a asp-area="" asp-page="/Privacy">Privacy</a>
  12. </div>
  13. </footer>
  14. <script src="~/lib/jquery/dist/jquery.js"></script>
  15. <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.js"></script>
  16. <script src="~/js/site.js" asp-append-version="true"></script>
  17. @RenderSection("Scripts", required: false)
  18. </body>
  19. </html>
  • _CookieConsentPartial文件添加到项目:
  1. @using Microsoft.AspNetCore.Http.Features
  2. @{
  3. var consentFeature = Context.Features.Get<ITrackingConsentFeature>();
  4. var showBanner = !consentFeature?.CanTrack ?? false;
  5. var cookieString = consentFeature?.CreateConsentCookie();
  6. }
  7. @if (showBanner)
  8. {
  9. <div id="cookieConsent" class="alert alert-info alert-dismissible fade show" role="alert">
  10. Use this space to summarize your privacy and cookie use policy. <a asp-page="/Privacy">Learn More</a>.
  11. <button type="button" class="accept-policy close" data-dismiss="alert" aria-label="Close" data-cookie-string="@cookieString">
  12. <span aria-hidden="true">Accept</span>
  13. </button>
  14. </div>
  15. <script>
  16. (function () {
  17. var button = document.querySelector("#cookieConsent button[data-cookie-string]");
  18. button.addEventListener("click", function (event) {
  19. document.cookie = button.dataset.cookieString;
  20. }, false);
  21. })();
  22. </script>
  23. }
  • 选择本文的 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 支持:

  • CookiePolicyOptionsUseCookiePolicyStartup 类中设置。
  • _CookieConsentPartial分部视图。此文件中包括 "接受" 按钮。用户单击 "接受" 按钮时,会提供许可来存储 cookie。
  • Pages/私密. cshtml页面或Views/Home/私密视图提供了一个页面,用于详细描述您的站点的隐私策略。_CookieConsentPartial文件生成指向隐私页面的链接。
  • 对于通过单独用户帐户创建的应用,"管理" 页提供了下载和删除个人用户数据的链接。

CookiePolicyOptions 和 UseCookiePolicyCookiePolicyOptions and UseCookiePolicy

CookiePolicyOptionsStartup.ConfigureServices中进行初始化:

  1. public class Startup
  2. {
  3. public Startup(IConfiguration configuration)
  4. {
  5. Configuration = configuration;
  6. }
  7. public IConfiguration Configuration { get; }
  8. // This method gets called by the runtime. Use this method to add services
  9. // to the container.
  10. public void ConfigureServices(IServiceCollection services)
  11. {
  12. services.Configure<CookiePolicyOptions>(options =>
  13. {
  14. // This lambda determines whether user consent for non-essential cookies
  15. // is needed for a given request.
  16. options.CheckConsentNeeded = context => true;
  17. options.MinimumSameSitePolicy = SameSiteMode.None;
  18. });
  19. services.AddDbContext<ApplicationDbContext>(options =>
  20. options.UseSqlServer(
  21. Configuration.GetConnectionString("DefaultConnection")));
  22. services.AddDefaultIdentity<IdentityUser>()
  23. .AddEntityFrameworkStores<ApplicationDbContext>();
  24. // If the app uses session state, call AddSession.
  25. // services.AddSession();
  26. services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
  27. }
  28. // This method gets called by the runtime. Use this method to configure the
  29. // HTTP request pipeline.
  30. public void Configure(IApplicationBuilder app, IHostingEnvironment env)
  31. {
  32. if (env.IsDevelopment())
  33. {
  34. app.UseDeveloperExceptionPage();
  35. app.UseDatabaseErrorPage();
  36. }
  37. else
  38. {
  39. app.UseExceptionHandler("/Error");
  40. app.UseHsts();
  41. }
  42. app.UseHttpsRedirection();
  43. app.UseStaticFiles();
  44. app.UseCookiePolicy();
  45. app.UseAuthentication();
  46. // If the app uses session state, call Session Middleware after Cookie
  47. // Policy Middleware and before MVC Middleware.
  48. // app.UseSession();
  49. app.UseMvc();
  50. }
  51. }

Startup.Configure中调用UseCookiePolicy

  1. public class Startup
  2. {
  3. public Startup(IConfiguration configuration)
  4. {
  5. Configuration = configuration;
  6. }
  7. public IConfiguration Configuration { get; }
  8. // This method gets called by the runtime. Use this method to add services
  9. // to the container.
  10. public void ConfigureServices(IServiceCollection services)
  11. {
  12. services.Configure<CookiePolicyOptions>(options =>
  13. {
  14. // This lambda determines whether user consent for non-essential cookies
  15. // is needed for a given request.
  16. options.CheckConsentNeeded = context => true;
  17. options.MinimumSameSitePolicy = SameSiteMode.None;
  18. });
  19. services.AddDbContext<ApplicationDbContext>(options =>
  20. options.UseSqlServer(
  21. Configuration.GetConnectionString("DefaultConnection")));
  22. services.AddDefaultIdentity<IdentityUser>()
  23. .AddEntityFrameworkStores<ApplicationDbContext>();
  24. // If the app uses session state, call AddSession.
  25. // services.AddSession();
  26. services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
  27. }
  28. // This method gets called by the runtime. Use this method to configure the
  29. // HTTP request pipeline.
  30. public void Configure(IApplicationBuilder app, IHostingEnvironment env)
  31. {
  32. if (env.IsDevelopment())
  33. {
  34. app.UseDeveloperExceptionPage();
  35. app.UseDatabaseErrorPage();
  36. }
  37. else
  38. {
  39. app.UseExceptionHandler("/Error");
  40. app.UseHsts();
  41. }
  42. app.UseHttpsRedirection();
  43. app.UseStaticFiles();
  44. app.UseCookiePolicy();
  45. app.UseAuthentication();
  46. // If the app uses session state, call Session Middleware after Cookie
  47. // Policy Middleware and before MVC Middleware.
  48. // app.UseSession();
  49. app.UseMvc();
  50. }
  51. }

_CookieConsentPartial 分部视图_CookieConsentPartial.cshtml partial view

_CookieConsentPartial分部视图:

  1. @using Microsoft.AspNetCore.Http.Features
  2. @{
  3. var consentFeature = Context.Features.Get<ITrackingConsentFeature>();
  4. var showBanner = !consentFeature?.CanTrack ?? false;
  5. var cookieString = consentFeature?.CreateConsentCookie();
  6. }
  7. @if (showBanner)
  8. {
  9. <nav id="cookieConsent" class="navbar navbar-default navbar-fixed-top" role="alert">
  10. <div class="container">
  11. <div class="navbar-header">
  12. <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#cookieConsent .navbar-collapse">
  13. <span class="sr-only">Toggle cookie consent banner</span>
  14. <span class="icon-bar"></span>
  15. <span class="icon-bar"></span>
  16. <span class="icon-bar"></span>
  17. </button>
  18. <span class="navbar-brand"><span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span></span>
  19. </div>
  20. <div class="collapse navbar-collapse">
  21. <p class="navbar-text">
  22. Use this space to summarize your privacy and cookie use policy.
  23. </p>
  24. <div class="navbar-right">
  25. <a asp-page="/Privacy" class="btn btn-info navbar-btn">Learn More</a>
  26. <button type="button" class="btn btn-default navbar-btn" data-cookie-string="@cookieString">Accept</button>
  27. </div>
  28. </div>
  29. </div>
  30. </nav>
  31. <script>
  32. (function () {
  33. document.querySelector("#cookieConsent button[data-cookie-string]").addEventListener("click", function (el) {
  34. document.cookie = el.target.dataset.cookieString;
  35. document.querySelector("#cookieConsent").classList.add("hidden");
  36. }, false);
  37. })();
  38. </script>
  39. }

此部分内容:

  • 获取用户的跟踪状态。如果应用配置为要求同意,则用户必须同意才能跟踪 cookie。如果需要同意,cookie 许可面板将固定在 _布局 cshtml文件创建的导航栏的顶部。
  • 提供 HTML <p> 元素,用于汇总隐私和 cookie 使用策略。
  • 提供指向隐私页面或视图的链接,您可以在其中详细说明网站的隐私策略。

重要 cookieEssential cookies

如果尚未提供存储 cookie 的许可,则仅将标记为 "重要" 的 cookie 发送到浏览器。以下代码使 cookie 非常重要:

  1. public IActionResult OnPostCreateEssentialAsync()
  2. {
  3. HttpContext.Response.Cookies.Append(Constants.EssentialSec,
  4. DateTime.Now.Second.ToString(),
  5. new CookieOptions() { IsEssential = true });
  6. ResponseCookies = Response.Headers[HeaderNames.SetCookie].ToString();
  7. return RedirectToPage("./Index");
  8. }

TempData 提供程序和会话状态 cookie 不重要TempData provider and session state cookies aren't essential

TempData 提供程序cookie 并不重要。如果禁用跟踪,则 TempData 提供程序不起作用。若要在禁用跟踪时启用 TempData 提供程序,请在 Startup.ConfigureServices中将 TempData cookie 标记为必要:

  1. // The TempData provider cookie is not essential. Make it essential
  2. // so TempData is functional when tracking is disabled.
  3. services.Configure<CookieTempDataProviderOptions>(options => {
  4. options.Cookie.IsEssential = true;
  5. });

会话状态cookie 并不重要。禁用跟踪后,会话状态不起作用。以下代码使会话 cookie 非常重要:

  1. services.AddSession(options =>
  2. {
  3. options.Cookie.IsEssential = true;
  4. });

个人数据Personal data

ASP.NET Core 通过单独用户帐户创建的应用包括下载和删除个人数据的代码。

选择用户名,然后选择 "个人数据":

管理个人数据页

说明:

  • 若要生成 Account/Manage 代码,请参阅基架标识
  • "删除" 和 "下载" 链接仅作用于默认标识数据。必须扩展用于创建自定义用户数据的应用,以删除/下载自定义用户数据。有关详细信息,请参阅向标识添加、下载和删除自定义用户数据
  • 对于存储在标识数据库表中的用户,保存的令牌 AspNetUserTokens 将在通过外键导致的级联删除行为删除用户时删除。
  • 外部提供程序身份验证(如 Facebook 和 Google)在接受 cookie 策略之前不可用。

静态加密Encryption at rest

某些数据库和存储机制允许静态加密。静态加密:

  • 自动加密存储的数据。
  • 对于访问数据的软件,不对其进行配置、编程或其他操作。
  • 是最简单且最安全的选项。
  • 允许数据库管理密钥和加密。

例如:

对于不提供静态内置加密的数据库,您可以使用磁盘加密来提供相同的保护。例如:

其他资源Additional resources