Skip to content

Commit

Permalink
GDPR Add/delete/download custom user data (#6829)
Browse files Browse the repository at this point in the history
* WIP: GDPR Add/delete/download custom user data

* Work

* Work

* Work

* Work

* Work

* Work

* Work

* Work
  • Loading branch information
Rick-Anderson authored Jun 5, 2018
1 parent 902f505 commit 5b3ec2d
Show file tree
Hide file tree
Showing 88 changed files with 26,044 additions and 15 deletions.
13 changes: 7 additions & 6 deletions aspnetcore/includes/scaffold-identity/id-scaffold-dlg-auth.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
Run the Identity scaffolder:

# [Visual Studio](#tab/visual-studio)
# [Visual Studio](#tab/visual-studio)

* From **Solution Explorer**, right-click on the project > **Add** > **New Scaffolded Item**.
* From the left pane of the **Add Scaffold** dialog, select **Identity** > **ADD**.
* In the **ADD Identity** dialog, select the options you want.
* Select your existing layout page, or your layout file will be overwritten with incorrect markup. When an existing _Layout.cshtml file is selected, it is **not** overwritten.

For example
`~/Pages/Shared/_Layout.cshtml` for Razor Pages
`~/Views/Shared/_Layout.cshtml` for MVC projects
* To use your existing data context, select at least one file to override. You must select at least one file to add your data context.
`~/Pages/Shared/_Layout.cshtml` for Razor Pages
`~/Views/Shared/_Layout.cshtml` for MVC projects
* To use your existing data context, select at least one file to override. You must select at least one file to add your data context.
* Select your data context class.
* Select **ADD**.
* To create a new user context and possibly create a custom user class for Identity:
* Select the **+** button to create a new **Data context class**.
* Select **ADD**.

Note: If you're creating a new user context, you don't have to select a file to override.

# [.NET Core CLI](#tab/netcore-cli)
Expand All @@ -30,7 +30,7 @@ dotnet tool install -g dotnet-aspnet-codegenerator
Add a package reference to [Microsoft.VisualStudio.Web.CodeGeneration.Design](https://www.nuget.org/packages/Microsoft.VisualStudio.Web.CodeGeneration.Design/) to the project (\*.csproj) file. Run the following command in the project directory:

```cli
dotnet add package Microsoft.VisualStudio.Web.CodeGeneration.Design --version 2.1.0
dotnet add package Microsoft.VisualStudio.Web.CodeGeneration.Design
dotnet restore
```

Expand All @@ -45,4 +45,5 @@ In the project folder, run the Identity scaffolder with the options you want. Fo
```cli
dotnet aspnet-codegenerator identity -dc MyWeb.Data.ApplicationDbContext --files Account.Register
```

-------------
10 changes: 5 additions & 5 deletions aspnetcore/includes/scaffold-identity/id-scaffold-dlg.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
Run the Identity scaffolder:

# [Visual Studio](#tab/visual-studio)
# [Visual Studio](#tab/visual-studio)

* From **Solution Explorer**, right-click on the project > **Add** > **New Scaffolded Item**.
* From the left pane of the **Add Scaffold** dialog, select **Identity** > **ADD**.
* In the **ADD Identity** dialog, select the options you want.
* Select your existing layout page, or your layout file will be overwritten with incorrect markup. For example
`~/Pages/Shared/_Layout.cshtml` for Razor Pages
`~/Views/Shared/_Layout.cshtml` for MVC projects
`~/Pages/Shared/_Layout.cshtml` for Razor Pages
`~/Views/Shared/_Layout.cshtml` for MVC projects
* Select the **+** button to create a new **Data context class**.
* Select **ADD**.

Expand All @@ -22,13 +22,12 @@ dotnet tool install -g dotnet-aspnet-codegenerator
Add a package reference to [Microsoft.VisualStudio.Web.CodeGeneration.Design](https://www.nuget.org/packages/Microsoft.VisualStudio.Web.CodeGeneration.Design/) to the project (\*.csproj) file. Run the following command in the project directory:

```cli
dotnet add package Microsoft.VisualStudio.Web.CodeGeneration.Design --version 2.1.0
dotnet add package Microsoft.VisualStudio.Web.CodeGeneration.Design
dotnet restore
```

Run the following command to list the Identity scaffolder options:


```cli
dotnet aspnet-codegenerator identity -h
```
Expand All @@ -38,4 +37,5 @@ In the project folder, run the Identity scaffolder with the options you want. Fo
```cli
dotnet aspnet-codegenerator identity --useDefaultUI
```

-------------
4 changes: 2 additions & 2 deletions aspnetcore/includes/scaffold-identity/migrations.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The generated Identity database code requires [Entity Framework Core Migrations](/ef/core/managing-schemas/migrations/). Create a migration and update the database. For example, run the following commands:

# [Visual Studio](#tab/visual-studio)
# [Visual Studio](#tab/visual-studio)

In the Visual Studio **Package Manager Console**:

Expand All @@ -18,4 +18,4 @@ dotnet ef database update

------

The "CreateIdentitySchema" name parameter for the `Add-Migration` command is arbitrary. `"CreateIdentitySchema" describes the migration.
The "CreateIdentitySchema" name parameter for the `Add-Migration` command is arbitrary. `"CreateIdentitySchema"` describes the migration.
164 changes: 164 additions & 0 deletions aspnetcore/security/authentication/add-user-data.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
---
title: Add, download, and delete custom user data to Identity in an ASP.NET Core project
author: rick-anderson
description: Learn how to add custom user data to Identity in an ASP.NET Core project. Delete data per GDPR.
manager: wpickett
monikerRange: '>= aspnetcore-2.1'
ms.author: riande
ms.date: 6/16/2018
ms.prod: asp.net-core
ms.technology: aspnet
ms.topic: article
uid: security/authentication/add-user-data
---
# Add, download, and delete custom user data to Identity in an ASP.NET Core project

By [Rick Anderson](https://twitter.com/RickAndMSFT)

This article shows how to:

* Add custom user data to an ASP.NET Core web app.
* Decorate the custom user data model with the [PersonalData](/dotnet/api/microsoft.aspnetcore.identity.personaldataattribute?view=aspnetcore-2.1) attribute so it's automatically available for download and deletion. Making the data able to be downloaded and deleted helps meet [GDPR](xref:security/gdpr) requirements.

The project sample is created from a Razor Pages web app, but the instructions are similar for a ASP.NET Core MVC web app.

[View or download sample code](https://github.com/aspnet/Docs/tree/live/aspnetcore/security/authentication/add-user-data/sample) ([how to download](xref:tutorials/index#how-to-download-a-sample))

## Prerequisites

[!INCLUDE [](~/includes/2.1-SDK.md)]

## Create a Razor web app

# [Visual Studio](#tab/visual-studio)

* From the Visual Studio **File** menu, select **New** > **Project**. Name the project **WebApp1** if you want to it match the namespace of the [download sample](https://github.com/aspnet/Docs/tree/live/aspnetcore/security/authentication/add-user-data/sample) code.
* Select **ASP.NET Core Web Application** > **OK**
* Select **ASP.NET Core 2.1** in the dropdown
* Select **Web Application** > **OK**
* Build and run the project.

# [.NET Core CLI](#tab/netcore-cli)

```cli
dotnet new webapp -o WebApp1
```

------

## Run the Identity scaffolder

# [Visual Studio](#tab/visual-studio)

* From **Solution Explorer**, right-click on the project > **Add** > **New Scaffolded Item**.
* From the left pane of the **Add Scaffold** dialog, select **Identity** > **ADD**.
* In the **ADD Identity** dialog, the following options:
* Select your existing layout file *~/Pages/Shared/_Layout.cshtml*
* Select the following files to override:
* **Account/Register**
* **Account/Manage/Index**
* Select the **+** button to create a new **Data context class**. Accept the type (**WebApp1.Models.WebApp1Context** if you named the project **WebApp1**).
* Select the **+** button to create a new **User class**. Accept the type (**WebApp1User** if you named the project **WebApp1**) > **Add**.
* Select **ADD**.

# [.NET Core CLI](#tab/netcore-cli)

If you have not previously installed the ASP.NET scaffolder, install it now:

```cli
dotnet tool install -g dotnet-aspnet-codegenerator
```

Add a package reference to [Microsoft.VisualStudio.Web.CodeGeneration.Design](https://www.nuget.org/packages/Microsoft.VisualStudio.Web.CodeGeneration.Design/) to the project (.csproj) file. Run the following command in the project directory:

```cli
dotnet add package Microsoft.VisualStudio.Web.CodeGeneration.Design
dotnet restore
```

Run the following command to list the Identity scaffolder options:

```cli
dotnet aspnet-codegenerator identity -h
```

In the project folder, run the Identity scaffolder:

```cli
dotnet aspnet-codegenerator identity -u WebApp1User -fi Account.Register;Account.Manage.Index
```

-------------

Follow the instruction in [Migrations, UseAuthentication, and layout](xref:security/authentication/scaffold-identity#efm) to perform the following steps:

* Create a migration and update the database.
* Add `UseAuthentication` to `Startup.Configure`.
* Add `<partial name="_LoginPartial" />` to the layout file.
* Test the app:
* Register a user
* Select the new user name (next to the **Logout** link). You might need to expand the window or select the navigation bar icon to show the user name and other links.
* Select the **Personal Data** tab.
* Select the **Download** button and examined the *PersonalData.json* file.
* Test the **Delete** button, which deletes the logged on user.

## Add custom user data to the Identity DB

Update the `IdentityUser` derived class with custom properties. If you named your project WebApp1, the file is named *Areas/Identity/Data/WebApp1User.cs*. Update the file with the following code:

[!code-csharp[Main](add-user-data/sample/Areas/Identity/Data/WebApp1User.cs)]

Properties decorated with the [PersonalData](/dotnet/api/microsoft.aspnetcore.identity.personaldataattribute?view=aspnetcore-2.1) attribute are:

* Are deleted when the *Areas/Identity/Pages/Account/Manage/DeletePersonalData.cshtml* Razor Page calls `UserManager.Delete`.
* Included in the downloaded data by the *Areas/Identity/Pages/Account/Manage/DownloadPersonalData.cshtml* Razor Page.

### Update the Account/Manage/Index.cshtml page

Update the `InputModel` in *Areas/Identity/Pages/Account/Manage/Index.cshtml.cs* with the following highlighted code:

[!code-csharp[Main](add-user-data/sample/Areas/Identity/Pages/Account/Manage/Index.cshtml.cs?name=snippet&highlight=28-36,63-64,87-95)]

Update the *Areas/Identity/Pages/Account/Manage/Index.cshtml* with the following highlighted markup:

[!code-html[Main](add-user-data/sample/Areas/Identity/Pages/Account/Manage/Index.cshtml?highlight=34-41)]

### Update the Account/Register.cshtml page

Update the `InputModel` in *Areas/Identity/Pages/Account/Register.cshtml.cs* with the following highlighted code:

[!code-csharp[Main](add-user-data/sample/Areas/Identity/Pages/Account/Register.cshtml.cs?name=snippet&highlight=8-16,43,44)]

Update the *Areas/Identity/Pages/Account/Register.cshtml* with the following highlighted markup:

[!code-html[Main](add-user-data/sample/Areas/Identity/Pages/Account/Register.cshtml?highlight=16-25)]

Build the project.

### Add a migration for the custom user data

# [Visual Studio](#tab/visual-studio)

In the Visual Studio **Package Manager Console**:

```PMC
Add-Migration CustomUserData
Update-Database
```

# [.NET Core CLI](#tab/netcore-cli)

```cli
dotnet ef migrations add CustomUserData
dotnet ef database update
```

------

## Test create, view, download, delete custom user data

Test the app:

* Register a new user.
* View the custom user data on the `/Identity/Account/Manage` page.
* Download and view the users personal data from the `/Identity/Account/Manage/PersonalData` page.
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using WebApp1.Areas.Identity.Data;

namespace WebApp1.Models
{
public class WebApp1Context : IdentityDbContext<WebApp1User>
{
public WebApp1Context(DbContextOptions<WebApp1Context> options)
: base(options)
{
}

protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
// Customize the ASP.NET Identity model and override the defaults if needed.
// For example, you can rename the ASP.NET Identity table names and more.
// Add your customizations after calling base.OnModelCreating(builder);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using Microsoft.AspNetCore.Identity;
using System;

namespace WebApp1.Areas.Identity.Data
{
public class WebApp1User : IdentityUser
{
[PersonalData]
public string Name { get; set; }
[PersonalData]
public DateTime DOB { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using WebApp1.Areas.Identity.Data;
using WebApp1.Models;

[assembly: HostingStartup(typeof(WebApp1.Areas.Identity.IdentityHostingStartup))]
namespace WebApp1.Areas.Identity
{
public class IdentityHostingStartup : IHostingStartup
{
public void Configure(IWebHostBuilder builder)
{
builder.ConfigureServices((context, services) => {
services.AddDbContext<WebApp1Context>(options =>
options.UseSqlServer(
context.Configuration.GetConnectionString("WebApp1ContextConnection")));

services.AddDefaultIdentity<WebApp1User>()
.AddEntityFrameworkStores<WebApp1Context>();
});
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
@page
@model DeletePersonalDataModel
@{
ViewData["Title"] = "Delete Personal Data";
ViewData["ActivePage"] = ManageNavPages.DeletePersonalData;
}

<h4>@ViewData["Title"]</h4>

<div class="alert alert-warning" role="alert">
<p>
<span class="glyphicon glyphicon-warning-sign"></span>
<strong>Deleting this data will permanently remove your account, and this cannot be recovered.</strong>
</p>
</div>

<div>
<form id="delete-user" method="post" class="form-group">
<div asp-validation-summary="All" class="text-danger"></div>
@if (Model.RequirePassword)
{
<div class="form-group">
<label asp-for="Input.Password"></label>
<input asp-for="Input.Password" class="form-control" />
<span asp-validation-for="Input.Password" class="text-danger"></span>
</div>
}
<button class="btn btn-danger" type="submit">Delete data and close my account</button>
</form>
</div>

@section Scripts {
<partial name="_ValidationScriptsPartial" />
}
Loading

0 comments on commit 5b3ec2d

Please sign in to comment.