Suporte a Regulamento Geral sobre a Proteção de Dados da UE (GDPR) no ASP.NET CoreEU General Data Protection Regulation (GDPR) support in ASP.NET Core

Por Rick AndersonBy Rick Anderson

ASP.NET Core fornece APIs e modelos para ajudar a atender a alguns dos requisitos de regulamento geral sobre a proteção de dados da UE (GDPR) :ASP.NET Core provides APIs and templates to help meet some of the EU General Data Protection Regulation (GDPR) requirements:

  • Os modelos de projeto incluem pontos de extensão e marcação fragmentado que você pode substituir por sua política de uso de privacidade e cookies.The project templates include extension points and stubbed markup that you can replace with your privacy and cookie use policy.
  • A página Pages/privacy. cshtml ou views/Home/privacy. cshtml fornece uma página para detalhar a política de privacidade do seu site.The Pages/Privacy.cshtml page or Views/Home/Privacy.cshtml view provides a page to detail your site's privacy policy.

Para habilitar o recurso de consentimento de cookie padrão como o encontrado nos modelos ASP.NET Core 2,2 em um aplicativo gerado pelo modelo ASP.NET Core 3,0: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:

  • Adicione using Microsoft.AspNetCore.Http à lista de diretivas using.Add using Microsoft.AspNetCore.Http to the list of using directives.

  • Adicione CookiePolicyOptions a Startup.ConfigureServices e UseCookiePolicy a Startup.Configure: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();
            });
        }
    }
    
  • Adicione o consentimento do cookie parcial ao arquivo _ layout. cshtml :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>
    
    
  • Adicione o _arquivo CookieConsentPartial. cshtml ao projeto: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>
    }
    
  • Selecione a versão ASP.NET Core 2,2 deste artigo para ler sobre o recurso de consentimento de cookie.Select the ASP.NET Core 2.2 version of this article to read about the cookie consent feature.

  • Os modelos de projeto incluem pontos de extensão e marcação fragmentado que você pode substituir por sua política de uso de privacidade e cookies.The project templates include extension points and stubbed markup that you can replace with your privacy and cookie use policy.
  • Um recurso de consentimento de cookie permite que você solicite (e rastreie) o consentimento de seus usuários para armazenar informações pessoais.A cookie consent feature allows you to ask for (and track) consent from your users for storing personal information. Se um usuário não tiver consentido a coleta de dados e o aplicativo tiver CheckConsentNeeded definido truecomo, os cookies não essenciais não serão enviados para o navegador.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.
  • Os cookies podem ser marcados como essenciais.Cookies can be marked as essential. Os cookies essenciais são enviados ao navegador mesmo quando o usuário não consentiu e o rastreamento está desabilitado.Essential cookies are sent to the browser even when the user hasn't consented and tracking is disabled.
  • Os cookies TempData e Session não são funcionais quando o rastreamento está desabilitado.TempData and Session cookies aren't functional when tracking is disabled.
  • A página gerenciar identidade fornece um link para baixar e excluir dados do usuário.The Identity manage page provides a link to download and delete user data.

O aplicativo de exemplo permite que você teste a maioria dos pontos de extensão GDPR e as APIs adicionadas aos modelos ASP.NET Core 2,1.The sample app allows you test most of the GDPR extension points and APIs added to the ASP.NET Core 2.1 templates. Consulte o arquivo Leiame para obter instruções de teste.See the ReadMe file for testing instructions.

Exibir ou baixar código de exemplo (como baixar)View or download sample code (how to download)

ASP.NET Core suporte a GDPR no código gerado por modeloASP.NET Core GDPR support in template-generated code

Os projetos Razor Pages e MVC criados com os modelos de projeto incluem o seguinte suporte a GDPR:Razor Pages and MVC projects created with the project templates include the following GDPR support:

  • CookiePolicyOptions e UseCookiePolicy são Startup definidos na classe.CookiePolicyOptions and UseCookiePolicy are set in the Startup class.
  • A exibição parcialde _CookieConsentPartial. cshtml .The _CookieConsentPartial.cshtml partial view. Um botão aceitar está incluído neste arquivo.An Accept button is included in this file. Quando o usuário clica no botão aceitar , o consentimento para armazenar cookies é fornecido.When the user clicks the Accept button, consent to store cookies is provided.
  • A página Pages/privacy. cshtml ou views/Home/privacy. cshtml fornece uma página para detalhar a política de privacidade do seu site.The Pages/Privacy.cshtml page or Views/Home/Privacy.cshtml view provides a page to detail your site's privacy policy. O arquivo CookieConsentPartial. cshtml gera um link para a página de privacidade. _The _CookieConsentPartial.cshtml file generates a link to the Privacy page.
  • Para aplicativos criados com contas de usuário individuais, a página Gerenciar fornece links para baixar e excluir dados de usuário pessoal.For apps created with individual user accounts, the Manage page provides links to download and delete personal user data.

CookiePolicyOptions e UseCookiePolicyCookiePolicyOptions and UseCookiePolicy

CookiePolicyOptions são inicializados Startup.ConfigureServicesem: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 é chamado em 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();
    }
}

_Exibição parcial de CookieConsentPartial. cshtml_CookieConsentPartial.cshtml partial view

A exibição parcial de _CookieConsentPartial. cshtml :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>
}

Isso parcial:This partial:

  • Obtém o estado do controle para o usuário.Obtains the state of tracking for the user. Se o aplicativo estiver configurado para exigir consentimento, o usuário deverá consentir antes que os cookies possam ser acompanhados.If the app is configured to require consent, the user must consent before cookies can be tracked. Se o consentimento for necessário, o painel de consentimento do cookie será corrigido na parte superior da barra de navegação criada pelo _arquivo layout. cshtml .If consent is required, the cookie consent panel is fixed at top of the navigation bar created by the _Layout.cshtml file.
  • Fornece um elemento <p> HTML para resumir sua política de privacidade e uso de cookies.Provides an HTML <p> element to summarize your privacy and cookie use policy.
  • Fornece um link para a página de privacidade ou a exibição em que você pode detalhar a política de privacidade do seu site.Provides a link to Privacy page or view where you can detail your site's privacy policy.

Cookies essenciaisEssential cookies

Se o consentimento para armazenar cookies não tiver sido fornecido, somente os cookies marcados como essenciais serão enviados para o navegador.If consent to store cookies hasn't been provided, only cookies marked essential are sent to the browser. O código a seguir torna um cookie essencial: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");
}

Os cookies de provedor TempData e estado de sessão não são essenciaisTempData provider and session state cookies aren't essential

O cookie do provedor TempData não é essencial.The TempData provider cookie isn't essential. Se o rastreamento estiver desabilitado, o provedor TempData não funcionará.If tracking is disabled, the TempData provider isn't functional. Para habilitar o provedor TempData quando o rastreamento estiver desabilitado, marque o cookie TempData como Startup.ConfigureServicesessencial em: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;
});

Os cookies de estado de sessão não são essenciais.Session state cookies are not essential. O estado da sessão não é funcional quando o rastreamento está desabilitado.Session state isn't functional when tracking is disabled. O código a seguir torna os cookies de sessão essenciais:The following code makes session cookies essential:

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

Dados pessoaisPersonal data

ASP.NET Core aplicativos criados com contas de usuário individuais incluem código para baixar e excluir dados pessoais.ASP.NET Core apps created with individual user accounts include code to download and delete personal data.

Selecione o nome de usuário e, em seguida, selecione dados pessoais:Select the user name and then select Personal data:

Página Gerenciar dados pessoais

Notas:Notes:

  • Para gerar o Account/Manage código, consulte identidade Scaffold.To generate the Account/Manage code, see Scaffold Identity.
  • Os links de exclusão e Download só agem nos dados de identidade padrão.The Delete and Download links only act on the default identity data. Aplicativos que criam dados de usuário personalizados devem ser estendidos para excluir/baixar os dados de usuário personalizados.Apps that create custom user data must be extended to delete/download the custom user data. Para obter mais informações, consulte Adicionar, baixar e excluir dados de usuário personalizados para identidade.For more information, see Add, download, and delete custom user data to Identity.
  • Os tokens salvos para o usuário que são armazenados na tabela AspNetUserTokens de banco de dados de identidade são excluídos quando o usuário é excluído por meio do comportamento de exclusão em cascata devido à chave estrangeira.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.
  • A autenticação de provedor externo, como o Facebook e o Google, não está disponível antes que a política de cookie seja aceita.External provider authentication, such as Facebook and Google, isn't available before the cookie policy is accepted.

Criptografia em repousoEncryption at rest

Alguns bancos de dados e mecanismos de armazenamento permitem a criptografia em repouso.Some databases and storage mechanisms allow for encryption at rest. Criptografia em repouso:Encryption at rest:

  • Criptografa os dados armazenados automaticamente.Encrypts stored data automatically.
  • Criptografa sem configuração, programação ou outro trabalho para o software que acessa os dados.Encrypts without configuration, programming, or other work for the software that accesses the data.
  • É a opção mais fácil e mais segura.Is the easiest and safest option.
  • Permite que o banco de dados gerencie chaves e criptografia.Allows the database to manage keys and encryption.

Por exemplo:For example:

Para bancos de dados que não fornecem criptografia interna em repouso, talvez você possa usar a criptografia de disco para fornecer a mesma proteção.For databases that don't provide built-in encryption at rest, you may be able to use disk encryption to provide the same protection. Por exemplo:For example:

Recursos adicionaisAdditional resources