Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GDPR Add/delete/download custom user data #6829

Merged
merged 9 commits into from
Jun 5, 2018
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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:

* Deleted by the *Areas/Identity/Pages/Account/Manage/DeletePersonalData.cshtml* Razor Page.
* 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