Asp.net core Identity
身份验证是确定用户身份的过程。 授权是确定用户是否有权访问资源的过程。
基本上正式项目都有用户中心模块,都需要实现身份验证和授权功能。Asp.net core中,微软官方给我们提供了Identity帮助我们实现这些功能。
如何使用Identity,下文将给出示例:
数据库
基本的配置就不再讲了,都是一样的,但是在自定义context这里:
public class MyContext : IdentityDbContext
{
}
不继承DbContext,而是继承IdentityDbContext(其实f12进去会发现IdentityDbContext是集成了DbContext的)。
依赖注入:
///efcore mysql
builder.Services.AddDbContext<MyContext>(opt =>
{
opt.UseMySql(builder.Configuration.GetConnectionString("Default"), MySqlServerVersion.LatestSupportedServerVersion);
});
//Identity
builder.Services.AddIdentity<IdentityUser, IdentityRole>().AddEntityFrameworkStores<MyContext>();
然后迁移,数据库里会多出几张表:
表中的字段都是预定义的,我们开发的时候经常会需要自定义一些字段,完全没有问题。IdentityDbContext支持泛型,创建一个user类继承IdentityUser,然后让MyContext继承泛型的IdentityDbContext就行了。
添加用户
Identity中提供了很多领域服务类,如UserManager,RoleManager,SignInManager,我们直接通过依赖注入就能使用,调用现成的方法来实现绝大部分功能。
[ApiController]
[Route("[controller]/[action]")]
public class UserController:ControllerBase
{
private readonly UserManager<IdentityUser> _userManager;
public UserController(UserManager<IdentityUser> userManager)
{
_userManager = userManager;
}
[HttpPost]
public async Task<IActionResult> CreateUserAsync(CreateUserDto input)
{
IdentityUser user = new IdentityUser();
user.UserName = input.UserName;
var result = await _userManager.CreateAsync(user, input.Password);
return Ok(result);
}
}
*:Identity默认的密码策略比较复杂,一般会在配置中进行更改:
builder.Services.Configure<IdentityOptions>(opt => { opt.Password.RequiredLength = 6; opt.Password.RequireNonAlphanumeric = false; opt.Password.RequireUppercase = false; opt.Password.RequireDigit = false; });
身份验证
也就是常说的登录。常见的方式有两种,一种是cookie/session,一种是jwt
Cookie/Session:
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme);
//这里注意顺序,Authentication要在Authorization前
app.UseAuthentication();
[Route("api/[controller]")]
[ApiController]
public class AuthController : ControllerBase
{
private readonly SignInManager<IdentityUser> _signInManager;
public AuthController(SignInManager<IdentityUser> signInManager)
{
_signInManager = signInManager;
}
[HttpPost("login")]
public async Task<IActionResult> Login(LoginUserDto loginUserDto)
{
var result = await _signInManager.PasswordSignInAsync(loginUserDto.UserName, loginUserDto.Password, true, false);
if (result.Succeeded)
{
return Ok("登录成功");
}
else
{
return Ok("登录失败");
}
}
}
在控制器类上或者action方法上使用特性[Authorize],此时如果没有登录或登录失败访问这些接口就会报错。
jwt:
builder.Services.AddAuthentication(options => {
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options => {
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,//是否验证Issuer
ValidateAudience = true,//是否验证Audience
ValidateLifetime = true,//是否验证失效时间
ClockSkew = TimeSpan.FromSeconds(30),
ValidateIssuerSigningKey = true,//是否验证SecurityKey
ValidAudience = JwtConst.Audience,//Audience
ValidIssuer = JwtConst.Issuer,//Issuer,这两项和前面签发jwt的设置一致
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(JwtConst.SecurityKey))//拿到SecurityKey
};
});
[HttpPost("login")]
public async Task<IActionResult> Login([FromBody]LoginUserDto loginUserDto)
{
var result = await _signInManager.PasswordSignInAsync(loginUserDto.UserName, loginUserDto.Password, false, false);
if (result.Succeeded)
{
//定义JWT的Payload部分
var claims = new[]
{
new Claim(ClaimTypes.Name, loginUserDto.UserName)
};
//生成token
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(JwtConst.SecurityKey));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var securityToken = new JwtSecurityToken(
issuer: JwtConst.Issuer,
audience: JwtConst.Audience,
claims: claims,
expires: DateTime.Now.AddDays(1),
signingCredentials: creds);
var token = new JwtSecurityTokenHandler().WriteToken(securityToken);
//返回token
return Ok(token);
}
else
{
return Ok("登录失败");
}
}
一些浏览器不支持cookie,比如微信小程序。这之后用谁做身份验证各有利弊,一般来说单体项目用cookie,微服务项目用jwt,但最后还是要看实际情况。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?