一.概述

接着上篇的WebAppIdentityDemo项目,将自定义用户数据添加到Identity DB,自定义扩展的用户数据类应继承IdentityUser类, 文件名为Areas / Identity / Data / {项目名称}User.cs。自定义的用户数据模型属性需要使用[PersonalData]来修饰,以便自动下载和删除。使数据能够下载和删除有助于满足GDPR要求。

  1.1 自定义用户数据类 WebAppIdentityDemo.Areas.Identity.Data。

    public class WebAppIdentityDemoUser:IdentityUser
{
/// <summary>
/// Full name
/// </summary>
[PersonalData]
public string Name { get; set; } /// <summary>
/// Birth Date
/// </summary>
[PersonalData]
public DateTime DOB { get; set; }
}

    使用属性修饰PersonalData特性是:

      使用Areas/Identity/Pages/Account/Manage/DeletePersonalData.cshtml 页调用UserManager.Delete

      使用Areas/Identity/Pages/Account/Manage/DownloadPersonalData.cshtml 页下载用户数据

  1.2 修改IdentityHostingStartup

    将Startup中有关identity的服务移到该文件中,好集中管理。

   public class IdentityHostingStartup : IHostingStartup
{
public void Configure(IWebHostBuilder builder)
{
builder.ConfigureServices((context, services) => {
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
context.Configuration.GetConnectionString("DefaultConnection"))); services.AddDefaultIdentity<WebAppIdentityDemoUser>()
.AddDefaultUI()
.AddEntityFrameworkStores<ApplicationDbContext>(); services.Configure<IdentityOptions>(options =>
{
// Password settings.
options.Password.RequireDigit = true;
options.Password.RequireLowercase = true;
options.Password.RequireNonAlphanumeric = true;
options.Password.RequireUppercase = true;
options.Password.RequiredLength = ;
options.Password.RequiredUniqueChars = ; // Lockout settings.
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes();
options.Lockout.MaxFailedAccessAttempts = ;
options.Lockout.AllowedForNewUsers = true; // User settings.
options.User.AllowedUserNameCharacters =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+";
options.User.RequireUniqueEmail = false;
}); services.ConfigureApplicationCookie(options =>
{
// Cookie settings
options.Cookie.HttpOnly = true;
options.ExpireTimeSpan = TimeSpan.FromMinutes(); options.LoginPath = $"/Identity/Account/Login";
options.LogoutPath = $"/Identity/Account/Logout";
options.AccessDeniedPath = $"/Identity/Account/AccessDenied";
});
});
}
}

  1.3 修改DbContext上下文

    // public class ApplicationDbContext : IdentityDbContext
public class ApplicationDbContext : IdentityDbContext<WebAppIdentityDemoUser>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
// Customize the ASP.NET Core Identity model and override the defaults if needed.
// For example, you can rename the ASP.NET Core Identity table names and more.
// Add your customizations after calling base.OnModelCreating(builder);
}
}

  1.4 数据库版本迁移

  PM> Add-Migration IdentitySchema2
  PM> Update-Database IdentitySchema2

  1.5 更新注册页面

    在开发中,会员系统要重用修改的页面,把IdentityUser 改成WebAppIdentityDemoUser。如果没改将报错:未解析到服务IdentityUser。红色部分为修改的代码

    [AllowAnonymous]
public class RegisterModel : PageModel
{
// private readonly SignInManager<IdentityUser> _signInManager;
//private readonly UserManager<IdentityUser> _userManager;
private readonly SignInManager<WebAppIdentityDemoUser> _signInManager;
private readonly UserManager<WebAppIdentityDemoUser> _userManager; private readonly ILogger<RegisterModel> _logger;
private readonly IEmailSender _emailSender; public RegisterModel(
UserManager<WebAppIdentityDemoUser> userManager,
SignInManager<WebAppIdentityDemoUser> signInManager,
ILogger<RegisterModel> logger,
IEmailSender emailSender)
{
_userManager = userManager;
_signInManager = signInManager;
_logger = logger;
_emailSender = emailSender;
} [BindProperty]
public InputModel Input { get; set; } public string ReturnUrl { get; set; } public class InputModel
{
[Required]
[DataType(DataType.Text)]
[Display(Name = "Full name")]
public string Name { get; set; } [Required]
[Display(Name = "Birth Date")]
[DataType(DataType.Date)]
public DateTime DOB { get; set; } [Required]
[EmailAddress]
[Display(Name = "Email")]
public string Email { get; set; } [Required]
[StringLength(, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = )]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; } [DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
} public void OnGet(string returnUrl = null)
{
ReturnUrl = returnUrl;
} public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
returnUrl = returnUrl ?? Url.Content("~/");
if (ModelState.IsValid)
{
// var user = new IdentityUser { UserName = Input.Email, Email = Input.Email };
var user = new WebAppIdentityDemoUser
{
UserName = Input.Email,
Email = Input.Email,
Name = Input.Name,
DOB = Input.DOB
};
var result = await _userManager.CreateAsync(user, Input.Password);
if (result.Succeeded)
{
_logger.LogInformation("User created a new account with password."); var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
var callbackUrl = Url.Page(
"/Account/ConfirmEmail",
pageHandler: null,
values: new { userId = user.Id, code = code },
protocol: Request.Scheme); await _emailSender.SendEmailAsync(Input.Email, "Confirm your email",
$"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>."); await _signInManager.SignInAsync(user, isPersistent: false);
return LocalRedirect(returnUrl);
}
foreach (var error in result.Errors)
{
ModelState.AddModelError(string.Empty, error.Description);
}
} // If we got this far, something failed, redisplay form
return Page();
}
}

  

@page
@model RegisterModel
@{
ViewData["Title"] = "Register";
} <h1>@ViewData["Title"]</h1> <div class="row">
<div class="col-md-4">
<form asp-route-returnUrl="@Model.ReturnUrl" method="post">
<h4>Create a new account.</h4>
<hr />
<div asp-validation-summary="All" class="text-danger"></div> <div class="form-group">
<label asp-for="Input.Name"></label>
<input asp-for="Input.Name" class="form-control" />
<span asp-validation-for="Input.Name" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Input.DOB"></label>
<input asp-for="Input.DOB" class="form-control" />
<span asp-validation-for="Input.DOB" class="text-danger"></span>
</div> <div class="form-group">
<label asp-for="Input.Email"></label>
<input asp-for="Input.Email" class="form-control" />
<span asp-validation-for="Input.Email" class="text-danger"></span>
</div>
<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>
<div class="form-group">
<label asp-for="Input.ConfirmPassword"></label>
<input asp-for="Input.ConfirmPassword" class="form-control" />
<span asp-validation-for="Input.ConfirmPassword" class="text-danger"></span>
</div>
<button type="submit" class="btn btn-primary">Register</button>
</form>
</div>
</div> @section Scripts {
<partial name="_ValidationScriptsPartial" />
}

    启动程序,运行注册页,保存成功后,查看数据库,如下所示:

  1.6 其它相关页修改

    下面这些最基本的页面,都需要把IdentityUser 改成WebAppIdentityDemoUser。

      登录页 /Identity/Account/Login

      注册页 Identity/Account/Register

      会员管理后台主页 /Identity/Account/Manage/index

      个人资料页 /Identity/Account/Manage/PersonalData

      个人资料删除 /Identity/Account/Manage/DeletePersonalData

      个人资料下载/Identity/Account/Manage/ DownloadPersonalData.cshtml

      分部页 _ManageNav.cshtml

  

  下面是 Account/Manage/Index.cshtml 页,已经加上自定义的二个用户字段信息,具体更新代码见官网

    下面是/Identity/Account/Manage/PersonalData.cshtml 页,已经可以下载和删除用户数据

  参考文献

    自定义用户数据

  

asp.net core系列 47 Identity 自定义用户数据的更多相关文章

  1. 【asp.net core 系列】15 自定义Identity

    0. 前言 在之前的文章中简单介绍了一下asp.net core中的Identity,这篇文章将继续针对Identity进行进一步的展开. 1. 给Identity添加额外的信息 在<[asp. ...

  2. asp.net core系列 48 Identity 身份模型自定义

    一.概述 ASP.NET Core Identity提供了一个框架,用于管理和存储在 ASP.NET Core 应用中的用户帐户. Identity添加到项目时单个用户帐户选择作为身份验证机制. 默认 ...

  3. asp.net core系列 46 Identity介绍

    一. Identity 介绍 ASP.NET Core Identity是一个会员系统,可为ASP.NET Core应用程序添加登录功能.可以使用SQL Server数据库配置身份以存储用户名,密码和 ...

  4. asp.net core系列 52 Identity 其它关注点

    一.登录分析 在使用identity身份验证登录时,在login中调用的方法是: var result = await _signInManager.PasswordSignInAsync(Input ...

  5. asp.net core利用DI实现自定义用户系统,脱离ControllerBase.User

    前言 很多时候其实我们并不需要asp.net core自带的那么复杂的用户系统,基于角色,各种概念,还得用EF Core,而且在web应用中都是把信息存储到cookie中进行通讯(我不喜欢放cooki ...

  6. asp.net core系列 49 Identity 授权(上)

    一.概述 授权是指用户能够访问资源的权限,如页面数据的查看.编辑.新增.删除.导出.下载等权限.ASP.NET Core 授权提供了多种且灵活的方式,包括:Razor pages授权约定.简单授权.R ...

  7. asp.net core系列 51 Identity 授权(下)

    1.6 基于资源的授权 前面二篇中,熟悉了五种授权方式(对于上篇讲的策略授权,还有IAuthorizationPolicyProvider的自定义授权策略提供程序没有讲,后面再补充).本篇讲的授权方式 ...

  8. asp.net core系列 50 Identity 授权(中)

    1.5 基于策略的授权 在上篇中,已经讲到了授权访问(authorization)的四种方式.其中Razor Pages授权约定和简单授权二种方式更像是身份认证(authentication) ,因为 ...

  9. 【目录】asp.net core系列篇

    随笔分类 - asp.net core系列篇 asp.net core系列 68 Filter管道过滤器 摘要: 一.概述 本篇详细了解一下asp.net core filters,filter叫&q ...

随机推荐

  1. [Micropython]TPYBoard v10x MFRC522智能门禁系统

    MF RC522 是应用于13.56MHz 非接触式通信中高集成度读写卡系列芯片中的一员.也就是射频卡. 经常忘带钥匙,最尴尬的上周竟然去开4楼的门,(家住五楼,无电梯),开了好一会没打开,事后对4楼 ...

  2. tomcat项目绑定到域名及运行内存配置

    一.tomcat中的项目绑定到域名通过域名访问 1.在tomcat下的conf/server.xml中找到Host修改(1.name为你的域名,2.配置Context中的path为空就是直接访问项目不 ...

  3. cocos2d-x学习之路之工作吐槽

    经过大半年的cocos2d-x的学习,目前已在一个游戏创业公司实习,负责客户端的代码编写和维护.公司做了一款网游.比较给力,马上就要发布了.希望能够大卖.比较坑的是,居然电脑不给联网.查资料都不好查, ...

  4. 【转】网上看到的“12个非常有用的JavaScript技巧”

    1) 使用!!将变量转换成布尔类型 有时,我们需要检查一些变量是否存在,或者它是否具有有效值,从而将它们的值视为true.对于做这样的检查,你可以使用!!(双重否定运算符),它能自动将任何类型的数据转 ...

  5. C++相关:C++的IO库

    前言 基本的IO库设施 istream(输入流类型),提供输入操作. ostream(输出流类型),提供输出操作. cin,一个istream对象,从标准输入读取数据. cout,一个ostream对 ...

  6. 爬虫-Python爬虫常用库

    一.常用库 1.requests 做请求的时候用到. requests.get("url") 2.selenium 自动化会用到. 3.lxml 4.beautifulsoup 5 ...

  7. SSM-Spring-22:Spring+Mybatis+JavaWeb的整合

    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 众所周知,框架Spring来整合别的框架,但是Mybatis出现的晚,Spring就没有给他提供支持,那怎么办 ...

  8. SSM-Spring-01:Spring的概念+入门案例

    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- Spring 提起Spring,就会想到企业级框架这个词 企业级系统: 1.大规模:用户数量多,数据规模庞大, ...

  9. jmeter添加断言

    先创建一个线程组,再创建一个http请求. 为了方便观察,我们添加两个监听器,察看结果树和断言结果. 添加断言:响应断言,响应断言也是比较常用的一个断言 设置响应断言:正常情况下响应代码是200.选择 ...

  10. JS(总结)

    基础 Javascript是一种弱类型语言,它分别有什么优点和缺点 弱类型语言:简单好用,更灵活多变.但是会牺牲性能,比如一些隐含的类型转换 强类型语言:类型转换的时候非常严格,,强类型语言是直接操纵 ...