ASP.NET Core での EU の一般データ保護規制 (GDPR) のサポート

作成者: Rick Anderson

ASP.NET Core には、EU の一般データ保護規制 (GDPR) 要件の一部を満たすのに役立つ API とテンプレートが用意されています。

  • プロジェクト テンプレートには、拡張ポイントとスタブされたマークアップが含まれており、お客様のプライバシーや cookie の使用ポリシーに置き換えることができます。
  • Pages/Privacy.cshtml ページまたは Views/Home/Privacy.cshtml ビューには、サイトのプライバシー ポリシーの詳細を表示するページが用意されています。

最新の 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();

上記のコードでは、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>
    }
    
  • cookie 同意機能については、この記事の ASP.NET Core 2.2 バージョンを参照してください。

ユーザーが 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 同意機能を使うと、個人情報の保存についての同意をユーザーに求める (および追跡する) ことができます。 ユーザーがデータ収集に同意しておらず、アプリで CheckConsentNeededtrue に設定されている場合、必須でない cookie はブラウザーに送信されません。
  • Cookie は必須としてマークできます。 必須の cookie は、ユーザーが同意しておらず追跡が無効になっている場合でも、ブラウザーに送信されます。
  • 追跡が無効になっている場合、TempData とセッション cookie は機能しません。
  • Identity の管理ページには、ユーザー データをダウンロードおよび削除するためのリンクが用意されています。

サンプル アプリを使うと、ASP.NET Core 2.1 テンプレートに追加された GDPR 拡張ポイントと API の大部分をテストできます。 テスト手順については、ReadMe ファイルを参照してください。

サンプル コードを表示またはダウンロードします (ダウンロード方法)。

テンプレートで生成されたコードでの ASP.NET Core GDPR のサポート

プロジェクト テンプレートで作成された Razor Pages と MVC プロジェクトには、次の GDPR サポートが含まれます。

  • CookiePolicyOptionsUseCookiePolicyStartup クラスに設定されます。
  • _CookieConsentPartial.cshtml部分ビュー。 このファイルには [Accept] ボタンが含まれています。 ユーザーが [Accept] ボタンをクリックすると、cookie の保存に同意したことになります。
  • Pages/Privacy.cshtml ページまたは Views/Home/Privacy.cshtml ビューには、サイトのプライバシー ポリシーの詳細を表示するページが用意されています。 _CookieConsentPartial.cshtml ファイルによって、Privacy ページへのリンクが生成されます。
  • 個人のユーザー アカウントで作成されたアプリの場合、[Manage] ページに、個人ユーザー データをダウンロードおよび削除するためのリンクが表示されます。

CookiePolicyOptions と UseCookiePolicy

CookiePolicyOptionsStartup.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();
    }
}

UseCookiePolicyStartup.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 を追跡するためにはユーザーが同意する必要があります。 同意が必要な場合は、_Layout.cshtml によって作成されたナビゲーション バーの上部に cookie 同意パネルが固定されます。
  • プライバシーと cookie の使用ポリシーを要約するための HTML <p> 要素が用意されています。
  • サイトのプライバシー ポリシーの詳細を確認できる 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 providercookie は必須ではありません。 追跡が無効になっている場合、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;
});

セッション状態cookies は必須ではありません。 追跡が無効になっている場合、セッション状態は機能しません。 次のコードでは、セッション cookie が必須になります。

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

個人データ

個人のユーザー アカウントで作成された ASP.NET Core アプリには、個人データをダウンロードおよび削除するためのコードが含まれています。

ユーザー名を選んでから、 [Personal data] を選びます。

Manage personal data page

注:

  • Account/Manage コードを生成するには、Identity のスキャフォールディングに関する記事を参照してください。
  • [Delete][Download] の各リンクは、既定の ID データに対してのみ機能します。 カスタム ユーザー データを作成するアプリは、カスタム ユーザー データを削除およびダウンロードするように拡張する必要があります。 詳細については、Identity へのカスタム ユーザー データの追加、ダウンロード、削除に関する記事を参照してください。
  • Identity データベース テーブル AspNetUserTokens に格納されているユーザーの保存済みトークンは、外部キーによる連鎖削除動作によってユーザーが削除されると、削除されます。
  • Facebook や Google などの外部プロバイダー認証は、cookie ポリシーが承認されないと使用できません。

保存時の暗号化

一部のデータベースとストレージのメカニズムでは、保存時の暗号化が可能です。 保存時の暗号化:

  • 保存されたデータが自動的に暗号化されます。
  • そのデータにアクセスするソフトウェアの構成、プログラミング、またはその他の作業なしで暗号化されます。
  • 最も簡単かつ安全なオプションです。
  • データベースでキーと暗号化を管理できるようになります。

次に例を示します。

保存時の暗号化が組み込まれていないデータベースについては、ディスク暗号化を使って同じ保護を提供できる場合があります。 次に例を示します。

その他の技術情報

  • プロジェクト テンプレートには、拡張ポイントとスタブされたマークアップが含まれており、お客様のプライバシーや cookie の使用ポリシーに置き換えることができます。
  • Pages/Privacy.cshtml ページまたは Views/Home/Privacy.cshtml ビューには、サイトのプライバシー ポリシーの詳細を表示するページが用意されています。

最新の ASP.NET Core テンプレートで生成されたアプリで、ASP.NET Core 2.2 テンプレートにあるような既定の cookie 同意機能を有効にするには:

  • using ディレクティブのリストに using Microsoft.AspNetCore.Http を追加します。

  • CookiePolicyOptionsStartup.ConfigureServices に、UseCookiePolicyStartup.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>
    }
    
  • cookie 同意機能については、この記事の ASP.NET Core 2.2 バージョンを参照してください。

  • プロジェクト テンプレートには、拡張ポイントとスタブされたマークアップが含まれており、お客様のプライバシーや cookie の使用ポリシーに置き換えることができます。
  • Pages/Privacy.cshtml ページまたは Views/Home/Privacy.cshtml ビューには、サイトのプライバシー ポリシーの詳細を表示するページが用意されています。

最新の 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();

上記のコードでは、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>
    }
    
  • cookie 同意機能については、この記事の ASP.NET Core 2.2 バージョンを参照してください。

保存時の暗号化

一部のデータベースとストレージのメカニズムでは、保存時の暗号化が可能です。 保存時の暗号化:

  • 保存されたデータが自動的に暗号化されます。
  • そのデータにアクセスするソフトウェアの構成、プログラミング、またはその他の作業なしで暗号化されます。
  • 最も簡単かつ安全なオプションです。
  • データベースでキーと暗号化を管理できるようになります。

次に例を示します。

保存時の暗号化が組み込まれていないデータベースについては、ディスク暗号化を使って同じ保護を提供できる場合があります。 次に例を示します。

その他の技術情報