aspnetcore/security/authentication/add-user-data.md
This article shows how to:
The project sample is created from a Razor Pages web app, but the instructions are similar for an ASP.NET Core MVC web app.
View or download sample code (how to download)
:::moniker range=">= aspnetcore-6.0"
dotnet new webapp -o WebApp1
~/Pages/Shared/_Layout.cshtmlIf you have not previously installed the ASP.NET Core scaffolder, install it now:
dotnet tool install -g dotnet-aspnet-codegenerator
Add a package reference to Microsoft.VisualStudio.Web.CodeGeneration.Design to the project (.csproj) file. Run the following command in the project directory:
dotnet add package Microsoft.VisualStudio.Web.CodeGeneration.Design
dotnet restore
Run the following command to list the Identity scaffolder options:
dotnet aspnet-codegenerator identity -h
In the project folder, run the Identity scaffolder:
dotnet aspnet-codegenerator identity -u WebApp1User -fi Account.Register;Account.Manage.Index
PowerShell uses semicolon as a command separator. When using PowerShell, escape the semi-colons in the file list or put the file list in double quotes.
Follow the instruction in Migrations, UseAuthentication, and layout to perform the following steps:
UseAuthentication to Program.cs<partial name="_LoginPartial" /> to the layout file.PersonalData.json file.Update the IdentityUser derived class with custom properties. If you named the project WebApp1, the file is named Areas/Identity/Data/WebApp1User.cs. Update the file with the following code:
Properties with the PersonalData attribute are:
Areas/Identity/Pages/Account/Manage/DeletePersonalData.cshtml Razor Page calls UserManager.Delete.Areas/Identity/Pages/Account/Manage/DownloadPersonalData.cshtml Razor Page.Account/Manage/Index.cshtml pageUpdate the InputModel in Areas/Identity/Pages/Account/Manage/Index.cshtml.cs with the following highlighted code:
Update the Areas/Identity/Pages/Account/Manage/Index.cshtml with the following highlighted markup:
Account/Register.cshtml pageUpdate the InputModel in Areas/Identity/Pages/Account/Register.cshtml.cs with the following highlighted code:
Update the Areas/Identity/Pages/Account/Register.cshtml with the following highlighted markup:
Build the project.
See Layout changes for instructions to add sign-in and sign-out links to every page.
In the Visual Studio Package Manager Console:
Add-Migration CustomUserData
Update-Database
dotnet ef migrations add CustomUserData
dotnet ef database update
Test the app:
/Identity/Account/Manage page./Identity/Account/Manage/PersonalData page.
:::moniker-end:::moniker range=">= aspnetcore-3.0 < aspnetcore-6.0"
dotnet new webapp -o WebApp1
~/Pages/Shared/_Layout.cshtmlIf you have not previously installed the ASP.NET Core scaffolder, install it now:
dotnet tool install -g dotnet-aspnet-codegenerator
Add a package reference to Microsoft.VisualStudio.Web.CodeGeneration.Design to the project (.csproj) file. Run the following command in the project directory:
dotnet add package Microsoft.VisualStudio.Web.CodeGeneration.Design
dotnet restore
Run the following command to list the Identity scaffolder options:
dotnet aspnet-codegenerator identity -h
In the project folder, run the Identity scaffolder:
dotnet aspnet-codegenerator identity -u WebApp1User -fi Account.Register;Account.Manage.Index
PowerShell uses semicolon as a command separator. When using PowerShell, escape the semi-colons in the file list or put the file list in double quotes.
Follow the instruction in Migrations, UseAuthentication, and layout to perform the following steps:
UseAuthentication to Startup.Configure.<partial name="_LoginPartial" /> to the layout file.PersonalData.json file.Update the IdentityUser derived class with custom properties. If you named the project WebApp1, the file is named Areas/Identity/Data/WebApp1User.cs. Update the file with the following code:
Properties with the PersonalData attribute are:
Areas/Identity/Pages/Account/Manage/DeletePersonalData.cshtml Razor Page calls UserManager.Delete.Areas/Identity/Pages/Account/Manage/DownloadPersonalData.cshtml Razor Page.Update the InputModel in Areas/Identity/Pages/Account/Manage/Index.cshtml.cs with the following highlighted code:
Update the Areas/Identity/Pages/Account/Manage/Index.cshtml with the following highlighted markup:
Update the InputModel in Areas/Identity/Pages/Account/Register.cshtml.cs with the following highlighted code:
Update the Areas/Identity/Pages/Account/Register.cshtml with the following highlighted markup:
Build the project.
In the Visual Studio Package Manager Console:
Add-Migration CustomUserData
Update-Database
dotnet ef migrations add CustomUserData
dotnet ef database update
Test the app:
/Identity/Account/Manage page./Identity/Account/Manage/PersonalData page.IUserClaimsPrincipalFactory<ApplicationUser>[!NOTE] This section isn't an extension of the previous tutorial. To apply the following steps to the app built using the tutorial, see this GitHub issue.
Additional claims can be added to ASP.NET Core Identity by using the IUserClaimsPrincipalFactory<T> interface. This class can be added to the app in the Startup.ConfigureServices method. Add the custom implementation of the class as follows:
public void ConfigureServices(IServiceCollection services)
{
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.AddScoped<IUserClaimsPrincipalFactory<ApplicationUser>,
AdditionalUserClaimsPrincipalFactory>();
The demo code uses the ApplicationUser class. This class adds an IsAdmin property which is used to add the additional claim.
public class ApplicationUser : IdentityUser
{
public bool IsAdmin { get; set; }
}
The AdditionalUserClaimsPrincipalFactory implements the UserClaimsPrincipalFactory interface. A new role claim is added to the ClaimsPrincipal.
public class AdditionalUserClaimsPrincipalFactory
: UserClaimsPrincipalFactory<ApplicationUser, IdentityRole>
{
public AdditionalUserClaimsPrincipalFactory(
UserManager<ApplicationUser> userManager,
RoleManager<IdentityRole> roleManager,
IOptions<IdentityOptions> optionsAccessor)
: base(userManager, roleManager, optionsAccessor)
{}
public async override Task<ClaimsPrincipal> CreateAsync(ApplicationUser user)
{
var principal = await base.CreateAsync(user);
var identity = (ClaimsIdentity)principal.Identity;
var claims = new List<Claim>();
if (user.IsAdmin)
{
claims.Add(new Claim(JwtClaimTypes.Role, "admin"));
}
else
{
claims.Add(new Claim(JwtClaimTypes.Role, "user"));
}
identity.AddClaims(claims);
return principal;
}
}
The additional claim can then be used in the app. In a Razor Page, the IAuthorizationService instance can be used to access the claim value.
@using Microsoft.AspNetCore.Authorization
@inject IAuthorizationService AuthorizationService
@if ((await AuthorizationService.AuthorizeAsync(User, "IsAdmin")).Succeeded)
{
<ul class="mr-auto navbar-nav">
<li class="nav-item">
<a class="nav-link" asp-controller="Admin" asp-action="Index">ADMIN</a>
</li>
</ul>
}
:::moniker-end
:::moniker range="< aspnetcore-3.0"
dotnet new webapp -o WebApp1
~/Pages/Shared/_Layout.cshtmlIf you have not previously installed the ASP.NET Core scaffolder, install it now:
dotnet tool install -g dotnet-aspnet-codegenerator
Add a package reference to Microsoft.VisualStudio.Web.CodeGeneration.Design to the project (.csproj) file. Run the following command in the project directory:
dotnet add package Microsoft.VisualStudio.Web.CodeGeneration.Design
dotnet restore
Run the following command to list the Identity scaffolder options:
dotnet aspnet-codegenerator identity -h
In the project folder, run the Identity scaffolder:
dotnet aspnet-codegenerator identity -u WebApp1User -fi Account.Register;Account.Manage.Index
PowerShell uses semicolon as a command separator. When using PowerShell, escape the semi-colons in the file list or put the file list in double quotes.
Follow the instruction in Migrations, UseAuthentication, and layout to perform the following steps:
UseAuthentication to Startup.Configure.<partial name="_LoginPartial" /> to the layout file.PersonalData.json file.Update the IdentityUser derived class with custom properties. If you named the project WebApp1, the file is named Areas/Identity/Data/WebApp1User.cs. Update the file with the following code:
Properties with the PersonalData attribute are:
Areas/Identity/Pages/Account/Manage/DeletePersonalData.cshtml Razor Page calls UserManager.Delete.Areas/Identity/Pages/Account/Manage/DownloadPersonalData.cshtml Razor Page.Update the InputModel in Areas/Identity/Pages/Account/Manage/Index.cshtml.cs with the following highlighted code:
Update the Areas/Identity/Pages/Account/Manage/Index.cshtml with the following highlighted markup:
Update the InputModel in Areas/Identity/Pages/Account/Register.cshtml.cs with the following highlighted code:
Update the Areas/Identity/Pages/Account/Register.cshtml with the following highlighted markup:
Build the project.
In the Visual Studio Package Manager Console:
Add-Migration CustomUserData
Update-Database
dotnet ef migrations add CustomUserData
dotnet ef database update
Test the app:
/Identity/Account/Manage page./Identity/Account/Manage/PersonalData page.:::moniker-end