ASP.NET Core 中的 EU 一般資料保護規定 (GDPR) 支援

作者:Rick Anderson

ASP.NET Core 提供 API 和範本,以協助符合某些 EU 一般資料保護規定 (GDPR) 需求:

  • 專案範本包括可取代為隱私權和 cookie 使用原則的擴充點和虛設常式標記。
  • Pages/Privacy.cshtml 頁面或 Views/Home/Privacy.cshtml 檢視會提供頁面來詳述網站的隱私權原則。

若要在目前 ASP.NET Core 範本產生的應用程式中啟用預設 cookie 同意功能 (例如,在 ASP.NET Core 2.2 範本中所找到的同意功能),請將下列醒目提示的程式碼新增至 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();

在上述程式碼中,會使用 CookiePolicyOptionsUseCookiePolicy

  • 將 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">
                &copy; 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 同意功能的相關資訊。

指定值,而此值用來追蹤使用者是否使用 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();

待用加密

某些資料庫和儲存體機制允許待用加密。 待用加密:

  • 自動加密所儲存的資料。
  • 在沒有設定、程式設計或其他可存取資料之軟體工作的情況下進行加密。
  • 是最簡單且最安全的選項。
  • 允許資料庫管理金鑰和加密。

例如:

針對未提供內建待用加密的資料庫,您可能可以使用磁碟加密來提供相同的保護。 例如:

其他資源

  • 專案範本包括可取代為隱私權和 cookie 使用原則的擴充點和虛設常式標記。
  • cookie 同意功能可讓您向使用者要求 (和追蹤) 同意來儲存個人資訊。 如果使用者尚未同意資料收集,而且應用程式已將 CheckConsentNeeded 設定為 true,則不會將非基本 cookie 傳送至瀏覽器。
  • Cookie 可以標記為基本。 即使使用者尚未同意且停用追蹤,還是會將基本 cookie 傳送至瀏覽器。
  • 停用追蹤時,TempData 和工作階段 cookie 無法運作。
  • Identity 管理頁面提供下載和刪除使用者資料的連結。

範例應用程式可讓您測試新增至 ASP.NET Core 2.1 範本的大部分 GDPR 擴充點和 API。 如需測試指示,請參閱讀我檔案

檢視或下載範例程式碼 \(英文\) (如何下載)

範本產生的程式碼中的 ASP.NET Core GDPR 支援

使用專案範本所建立的 Razor 頁面和 MVC 專案包括下列 GDPR 支援:

  • CookiePolicyOptionsUseCookiePolicy 設定於 Startup 類別中。
  • _CookieConsentPartial.cshtml部分檢視。 此檔案中包括 [接受] 按鈕。 使用者按一下 [接受] 按鈕時,表示同意儲存 cookie。
  • Pages/Privacy.cshtml 頁面或 Views/Home/Privacy.cshtml 檢視會提供頁面來詳述網站的隱私權原則。 _CookieConsentPartial.cshtml 檔案會產生 Privacy 頁面的連結。
  • 針對使用個別使用者帳戶所建立的應用程式,[管理] 頁面會提供下載和刪除個人使用者資料的連結。

CookiePolicyOptions 和使用Cookie原則

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> 元素來摘要說明您的隱私權和 cookie 使用原則。
  • 提供 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 應用程式包括可下載和刪除個人資料的程式碼。

選取使用者名稱,然後選取 [個人資料]

Manage personal data page

注意:

  • 若要產生 Account/Manage 程式碼,請參閱建構 Identity
  • [刪除] 和 [下載] 連結只會處理預設身分識別資料。 必須擴充可建立自訂使用者資料的應用程式,才能刪除/下載自訂使用者資料。 如需詳細資訊,請參閱在 Identity 中新增、下載和刪除自訂使用者資料
  • 外鍵而透過串聯刪除行為來刪除使用者時,會刪除 Identity 資料庫表格 AspNetUserTokens 中所儲存使用者的已儲存權杖。
  • 接受 cookie 原則之前,無法使用 Facebook 和 Google 這類外部提供者驗證

待用加密

某些資料庫和儲存體機制允許待用加密。 待用加密:

  • 自動加密所儲存的資料。
  • 在沒有設定、程式設計或其他可存取資料之軟體工作的情況下進行加密。
  • 是最簡單且最安全的選項。
  • 允許資料庫管理金鑰和加密。

例如:

針對未提供內建待用加密的資料庫,您可能可以使用磁碟加密來提供相同的保護。 例如:

其他資源

  • 專案範本包括可取代為隱私權和 cookie 使用原則的擴充點和虛設常式標記。
  • Pages/Privacy.cshtml 頁面或 Views/Home/Privacy.cshtml 檢視會提供頁面來詳述網站的隱私權原則。

在目前 ASP.NET Core 範本產生的應用程式中啟用預設 cookie 同意功能 (例如,在 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">
                &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.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 同意功能的相關資訊。

  • 專案範本包括可取代為隱私權和 cookie 使用原則的擴充點和虛設常式標記。
  • Pages/Privacy.cshtml 頁面或 Views/Home/Privacy.cshtml 檢視會提供頁面來詳述網站的隱私權原則。

若要在目前 ASP.NET Core 範本產生的應用程式中啟用預設 cookie 同意功能 (例如,在 ASP.NET Core 2.2 範本中所找到的同意功能),請將下列醒目提示的程式碼新增至 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();

在上述程式碼中,會使用 CookiePolicyOptionsUseCookiePolicy

  • 將 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">
                &copy; 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 同意功能的相關資訊。

待用加密

某些資料庫和儲存體機制允許待用加密。 待用加密:

  • 自動加密所儲存的資料。
  • 在沒有設定、程式設計或其他可存取資料之軟體工作的情況下進行加密。
  • 是最簡單且最安全的選項。
  • 允許資料庫管理金鑰和加密。

例如:

針對未提供內建待用加密的資料庫,您可能可以使用磁碟加密來提供相同的保護。 例如:

其他資源