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>
    }
    
  • 이 문서의 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 동의 기능을 사용하면 개인 정보를 저장하기 위해 사용자의 동의를 요청(및 추적)할 수 있습니다. 사용자가 데이터 수집에 동의하지 않았고 앱이 설정된 true경우 필수cookie적이지 않은 항목은 CheckConsentNeeded 브라우저로 전송되지 않습니다.
  • Cookie는 필수로 표시될 수 있습니다. 사용자가 동의하지 않았고 추적이 비활성화된 경우에도 필수 cookie가 브라우저로 전송됩니다.
  • 추적을 비활성화하면 TempData 및 세션 cookie가 작동하지 않습니다.
  • Identity 관리 페이지에서는 사용자 데이터를 다운로드하고 삭제할 수 있는 링크를 제공합니다.

샘플 앱을 사용하면 ASP.NET Core 2.1 템플릿에 추가된 대부분의 GDPR 확장점 및 API를 테스트할 수 있습니다. 테스트 지침은 추가 정보 파일을 참조하세요.

샘플 코드 보기 및 다운로드(다운로드 방법)

템플릿 생성 코드의 ASP.NET Core GDPR 지원

프로젝트 템플릿을 통해 만든 Razor Pages 및 MVC 프로젝트에는 다음과 같은 GDPR 지원이 포함됩니다.

  • CookiePolicyOptionsUseCookiePolicyStartup 클래스에서 설정됩니다.
  • _CookieConsentPartial.cshtml부분 보기입니다. 수락 단추가 이 파일에 포함되어 있습니다. 사용자가 동의 단추를 클릭하면 cookie 저장에 대한 동의가 제공됩니다.
  • Pages/Privacy.cshtml 페이지 또는 Views/Home/Privacy.cshtml 보기는 사이트의 개인 정보 취급 방침을 자세히 설명하는 페이지를 제공합니다. _CookieConsentPartial.cshtml 파일에서 Privacy 페이지에 대한 링크를 생성합니다.
  • 개별 사용자 계정으로 만든 앱의 경우 관리 페이지에서 개인 사용자 데이터를 다운로드하고 삭제하기 위한 링크를 제공합니다.

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를 추적할 수 있습니다. 동의가 필요한 경우 cookie 동의 패널은 _Layout.cshtml 파일에서 만든 탐색 모음의 맨 위에 고정됩니다.
  • 개인 정보 및 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 공급업체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를 참조하세요.
  • 삭제다운로드 링크는 기본 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>
    }
    
  • 이 문서의 ASP.NET Core 2.2 버전을 선택하여 cookie 동의 기능에 대해 읽어보십시오.

  • 프로젝트 템플릿에는 개인 정보 및 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>
    }
    
  • 이 문서의 ASP.NET Core 2.2 버전을 선택하여 cookie 동의 기능에 대해 읽어보세요.

휴지 상태의 암호화

일부 데이터베이스 및 스토리지 메커니즘은 저장 데이터 암호화를 허용합니다. 미사용 암호화:

  • 저장된 데이터를 자동으로 암호화합니다.
  • 데이터에 액세스하는 소프트웨어에 대한 구성, 프로그래밍 또는 기타 작업 없이 암호화합니다.
  • 가장 쉽고 안전한 옵션입니다.
  • 데이터베이스에서 키 및 암호화를 관리할 수 있습니다.

예시:

기본 제공 저장 데이터 암호화를 제공하지 않는 데이터베이스의 경우 디스크 암호화를 사용하여 동일한 보호를 제공할 수 있습니다. 예시:

추가 리소스