ASP.NET Core 中的 EU 一般資料保護規定(GDPR)支援EU General Data Protection Regulation (GDPR) support in ASP.NET Core

作者:Rick AndersonBy Rick Anderson

ASP.NET Core 提供 Api 和範本,以協助符合歐盟一般資料保護規定(GDPR)需求:ASP.NET Core provides APIs and templates to help meet some of the EU General Data Protection Regulation (GDPR) requirements:

  • 專案範本包括擴充點和 stub 標記,您可以將其取代為您的隱私權和 cookie 使用原則。The project templates include extension points and stubbed markup that you can replace with your privacy and cookie use policy.
  • [ Pages/隱私權] 頁面或 [ Views/Home/隱私權] 視圖會提供頁面,以詳細說明網站的隱私權原則。The Pages/Privacy.cshtml page or Views/Home/Privacy.cshtml view provides a page to detail your site's privacy policy.

若要啟用預設的 cookie 同意功能,例如在 ASP.NET Core 3.0 範本產生的應用程式的 ASP.NET Core 2.2 範本中找到:To enable the default cookie consent feature like that found in the ASP.NET Core 2.2 templates in an ASP.NET Core 3.0 template generated app:

  • using Microsoft.AspNetCore.Http加入 using 指示詞的清單。Add using Microsoft.AspNetCore.Http to the list of using directives.

  • CookiePolicyOptions新增Startup.ConfigureServices至,並Startup.ConfigureUseCookiePolicy 至:Add CookiePolicyOptions to Startup.ConfigureServices and UseCookiePolicy to 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檔案:Add the cookie consent partial to the _Layout.cshtml file:

            @*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">
                &copy; 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 檔案新增至專案: _Add the _CookieConsentPartial.cshtml file to the project:

    @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 同意功能的相關資訊。Select the ASP.NET Core 2.2 version of this article to read about the cookie consent feature.

  • 專案範本包括擴充點和 stub 標記,您可以將其取代為您的隱私權和 cookie 使用原則。The project templates include extension points and stubbed markup that you can replace with your privacy and cookie use policy.
  • Cookie 同意功能可讓您向使用者要求(並追蹤)同意,以儲存個人資訊。A cookie consent feature allows you to ask for (and track) consent from your users for storing personal information. 如果使用者尚未同意資料收集,而應用程式已將CheckConsentNeeded設定為true,則不會將非必要的 cookie 傳送至瀏覽器。If a user hasn't consented to data collection and the app has CheckConsentNeeded set to true, non-essential cookies aren't sent to the browser.
  • Cookie 可以標示為必要。Cookies can be marked as essential. 即使使用者尚未同意,也會將必要的 cookie 傳送至瀏覽器,而且會停用追蹤。Essential cookies are sent to the browser even when the user hasn't consented and tracking is disabled.
  • 停用追蹤時,TempData 和會話 cookie無法正常運作。TempData and Session cookies aren't functional when tracking is disabled.
  • [身分識別管理] 頁面提供下載和刪除使用者資料的連結。The Identity manage page provides a link to download and delete user data.

範例應用程式可讓您測試新增至 ASP.NET Core 2.1 範本的大部分 GDPR 擴充點和 api。The sample app allows you test most of the GDPR extension points and APIs added to the ASP.NET Core 2.1 templates. 如需測試指示,請參閱自述檔。See the ReadMe file for testing instructions.

檢視或下載範例程式碼 (英文) (如何下載)View or download sample code (how to download)

在範本產生的程式碼中 ASP.NET Core GDPR 支援ASP.NET Core GDPR support in template-generated code

使用專案範本建立的 Razor Pages 和 MVC 專案包含下列 GDPR 支援:Razor Pages and MVC projects created with the project templates include the following GDPR support:

  • CookiePolicyOptionsUseCookiePolicy是在Startup類別中設定。CookiePolicyOptions and UseCookiePolicy are set in the Startup class.
  • _CookieConsentPartial部分視圖The _CookieConsentPartial.cshtml partial view. 此檔案包含 [接受] 按鈕。An Accept button is included in this file. 當使用者按一下 [接受] 按鈕時,就會提供同意存放區 cookie。When the user clicks the Accept button, consent to store cookies is provided.
  • [ Pages/隱私權] 頁面或 [ Views/Home/隱私權] 視圖會提供頁面,以詳細說明網站的隱私權原則。The Pages/Privacy.cshtml page or Views/Home/Privacy.cshtml view provides a page to detail your site's privacy policy. CookieConsentPartial 會產生 [隱私權] 頁面的連結。 _The _CookieConsentPartial.cshtml file generates a link to the Privacy page.
  • 針對使用個別使用者帳戶所建立的應用程式,[管理] 頁面會提供下載和刪除個人使用者資料的連結。For apps created with individual user accounts, the Manage page provides links to download and delete personal user data.

CookiePolicyOptions 和 UseCookiePolicyCookiePolicyOptions and UseCookiePolicy

CookiePolicyOptions在中Startup.ConfigureServices初始化:CookiePolicyOptions are initialized in 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呼叫:UseCookiePolicy is called in 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 partial view

_CookieConsentPartial的部分視圖:The _CookieConsentPartial.cshtml partial view:

@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>
}

這部分:This partial:

  • 取得使用者的追蹤狀態。Obtains the state of tracking for the user. 如果應用程式已設定為需要同意,使用者必須先同意,才能追蹤 cookie。If the app is configured to require consent, the user must consent before cookies can be tracked. 如果需要同意,cookie 同意面板會固定在配置 _. cshtml檔案所建立的導覽列上方。If consent is required, the cookie consent panel is fixed at top of the navigation bar created by the _Layout.cshtml file.
  • 提供 HTML <p>元素來總結您的隱私權與 cookie 使用原則。Provides an HTML <p> element to summarize your privacy and cookie use policy.
  • 提供 [隱私權] 頁面或 [流覽] 的連結,您可以在其中詳細說明網站的隱私權原則。Provides a link to Privacy page or view where you can detail your site's privacy policy.

基本 cookieEssential cookies

如果尚未提供同意存放區 cookie,則只會將標示為必要的 cookie 傳送至瀏覽器。If consent to store cookies hasn't been provided, only cookies marked essential are sent to the browser. 下列程式碼會讓 cookie 變得很重要:The following code makes a cookie essential:

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 並不重要。The TempData provider cookie isn't essential. 如果停用追蹤,TempData 提供者就無法運作。If tracking is disabled, the TempData provider isn't functional. 若要在停用追蹤時啟用 TempData 提供者,請在中將 TempData Startup.ConfigureServicescookie 標記為必要項:To enable the TempData provider when tracking is disabled, mark the TempData cookie as essential in Startup.ConfigureServices:

// 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 並不重要。Session state cookies are not essential. 停用追蹤時,會話狀態無法運作。Session state isn't functional when tracking is disabled. 下列程式碼會讓會話 cookie 變得很重要:The following code makes session cookies essential:

services.AddSession(options =>
{
    options.Cookie.IsEssential = true;
});

個人資料Personal data

使用個別使用者帳戶所建立 ASP.NET Core 應用程式包含下載和刪除個人資料的程式碼。ASP.NET Core apps created with individual user accounts include code to download and delete personal data.

選取使用者名稱,然後選取 [個人資料]:Select the user name and then select Personal data:

管理個人資料頁面

附註:Notes:

  • 若要產生Account/Manage程式碼,請參閱Scaffold IdentityTo generate the Account/Manage code, see Scaffold Identity.
  • [刪除] 和 [下載] 連結只會對預設身分識別資料採取行動。The Delete and Download links only act on the default identity data. 建立自訂使用者資料的應用程式必須擴充,才能刪除/下載自訂使用者資料。Apps that create custom user data must be extended to delete/download the custom user data. 如需詳細資訊,請參閱將自訂使用者資料新增、下載及刪除至身分識別For more information, see Add, download, and delete custom user data to Identity.
  • 當使用者因為外鍵而透過串聯刪除行為刪除時, AspNetUserTokens會刪除儲存在身分識別資料庫資料表中之使用者的已儲存權杖。Saved tokens for the user that are stored in the Identity database table AspNetUserTokens are deleted when the user is deleted via the cascading delete behavior due to the foreign key.
  • 在接受 cookie 原則之前,無法使用外部提供者驗證(例如 Facebook 和 Google)。External provider authentication, such as Facebook and Google, isn't available before the cookie policy is accepted.

待用加密Encryption at rest

某些資料庫和儲存機制允許待用加密。Some databases and storage mechanisms allow for encryption at rest. 待用加密:Encryption at rest:

  • 自動加密儲存的資料。Encrypts stored data automatically.
  • 針對存取資料的軟體,不需要設定、程式設計或其他工作即可進行加密。Encrypts without configuration, programming, or other work for the software that accesses the data.
  • 是最簡單且最安全的選項。Is the easiest and safest option.
  • 允許資料庫管理金鑰和加密。Allows the database to manage keys and encryption.

例如:For example:

對於未提供內建靜態加密的資料庫,您可以使用磁片加密來提供相同的保護。For databases that don't provide built-in encryption at rest, you may be able to use disk encryption to provide the same protection. 例如:For example:

其他資源Additional resources