主题
本篇我将会介绍验证用户的机制当账户被创建的时候,同样 这个过程主要有IUserValidator这个接口来实现的,和密码验证一样Identity同样也内置已经实现好的账户验证。账户验证的比较简单,我会先介绍内置的IUserValidator的使用,然后会简单介绍一些源代码,最后会演示怎实现一个自定义的IUserValidator。
使用内置的IUserValidator来定义用户户名的规则
用户名验证规则是在Startup类 里面进行配置的,通过用IdentityOptions.User进行配置,IdentityOptions.User是UserOptions类的实例。UserOptions属性的列表如下:
- AllowedUserNameCharacters :类型string 代表用户创建用户名可以使用的字符,默认为:abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+
- RequireUniqueEmail :类型 bool,true 代表创建账户使用的email必须是没有被用过的。
现在Startup类中的ConfigureServices方法配置用户名验证规则,代码如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24public void ConfigureServices(IServiceCollection services)
{
//注入自定义密码验证类
services.AddTransient<IPasswordValidator<AppUser>,
CustomPasswordValidator>();
services.AddDbContext<AppIdentityDbContext>(options =>
options.UseSqlServer(
Configuration["Data:AppStoreIdentity:ConnectionString"]));
//配置
services.AddIdentity<AppUser, IdentityRole>(opts => {
//配置用户名验证规则
opts.User.RequireUniqueEmail = true;
opts.User.AllowedUserNameCharacters = "testabc";
//配置密码强度
opts.Password.RequiredLength = 6;
opts.Password.RequireNonAlphanumeric = false;
opts.Password.RequireLowercase = false;
opts.Password.RequireUppercase = false;
opts.Password.RequireDigit = false;
}).AddEntityFrameworkStores<AppIdentityDbContext>()
.AddDefaultTokenProviders();
services.AddMvc();
}
- 当用户创建账户时候要求email必须是未使用过的,用户名仅包含 testabc 这里面的字符。
我们启动网站,创建一个账户,看一下配置是否生效,结果如下图:
自定义用户验证
虽然内置的用户验证可以满足很多场景,但是假如我们要求创建的拥护都要包含test@163.com这个后缀时,我们就需要自定义一个用户验证类了。
IUserValidator接口的源代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Threading;
using System.Threading.Tasks;
namespace Microsoft.AspNetCore.Identity
{
/// <summary>
/// Provides an abstraction for user validation.
/// </summary>
/// <typeparam name="TUser">The type encapsulating a user.</typeparam>
public interface IUserValidator<TUser> where TUser : class
{
/// <summary>
/// Validates the specified <paramref name="user"/> as an asynchronous operation.
/// </summary>
/// <param name="manager">The <see cref="UserManager{TUser}"/> that can be used to retrieve user properties.</param>
/// <param name="user">The user to validate.</param>
/// <returns>The <see cref="Task"/> that represents the asynchronous operation, containing the <see cref="IdentityResult"/> of the validation operation.</returns>
Task<IdentityResult> ValidateAsync(UserManager<TUser> manager, TUser user);
}
}该接口很简单就包含了 ValidateAsync方法,用于验证用户名,
实现IUserValidator 接口
在Infrastructure文件夹中创建一个CustomUserValidator C#文件,代码如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20using System.Threading.Tasks;
using DemoUser.Models;
using Microsoft.AspNetCore.Identity;
namespace DemoUser.Infrastructure
{
public class CustomUserValidator
{
public Task<IdentityResult> ValidateAsync(UserManager<AppUser> manager,
AppUser user) {
if (user.Email.ToLower().EndsWith("test@163.com")) {
return Task.FromResult(IdentityResult.Success);
} else {
return Task.FromResult(IdentityResult.Failed(new IdentityError {
Code = "EmailError",
Description = "仅仅可以包含test@163.com后缀"
}));
} }
}
}- 我们在Startup类中的ConfigureServices 注入我们自定义的CustomUserValidator类,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28public void ConfigureServices(IServiceCollection services)
{
//注入自定义用户名验证类
services.AddTransient<IUserValidator<AppUser>,
CustomUserValidator>();
//注入自定义密码验证类
services.AddTransient<IPasswordValidator<AppUser>,
CustomPasswordValidator>();
services.AddDbContext<AppIdentityDbContext>(options =>
options.UseSqlServer(
Configuration["Data:AppStoreIdentity:ConnectionString"]));
//配置
services.AddIdentity<AppUser, IdentityRole>(opts => {
//配置用户名验证规则
opts.User.RequireUniqueEmail = true;
opts.User.AllowedUserNameCharacters = "testabc";
//配置密码强度
opts.Password.RequiredLength = 6;
opts.Password.RequireNonAlphanumeric = false;
opts.Password.RequireLowercase = false;
opts.Password.RequireUppercase = false;
opts.Password.RequireDigit = false;
}).AddEntityFrameworkStores<AppIdentityDbContext>()
.AddDefaultTokenProviders();
services.AddMvc();
}
这样我们就成功替换掉内置的用户验证类了。重新运行程序就可以了。
后记
这篇介绍了IUserValidator的使用方法,以及如何自定义我们自己的规则。从下一篇开始我打算开始介绍如何用Identity来对用户进行验证和授权。
github地址 对应分支f5- 我们在Startup类中的ConfigureServices 注入我们自定义的CustomUserValidator类,代码如下: