目录
身份验证是现代 Web 应用程序安全架构的核心组成部分。ASP.NET 提供了多种身份验证机制,每种机制都有其独特的原理和适用场景。本文将深入探讨 ASP.NET 中的各种身份验证方式,包括它们的实现原理、代码示例、对比分析以及最佳实践。
一、身份验证基础概念
身份验证(Authentication)是确认用户身份的过程,与之相关的授权(Authorization)则是确定已验证用户有哪些权限。在 ASP.NET 中,身份验证通常通过中间件实现,并与 ASP.NET Core 的身份系统集成。
二、ASP.NET 主要身份验证方式
1. Cookie 身份验证
原理:服务器在用户登录成功后创建一个加密的 Cookie,包含用户身份信息。后续请求中,浏览器会自动发送此 Cookie,服务器验证后识别用户身份。
实现代码:
// Startup.cs 配置
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.LoginPath = "/Account/Login";
options.AccessDeniedPath = "/Account/AccessDenied";
options.ExpireTimeSpan = TimeSpan.FromMinutes(30);
options.SlidingExpiration = true;
});
// 登录控制器
[HttpPost]
public async Task<IActionResult> Login(LoginModel model)
{
if (ModelState.IsValid)
{
var user = await _userService.Authenticate(model.Username, model.Password);
if (user != null)
{
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, user.Username),
new Claim(ClaimTypes.Role, user.Role)
};
var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
var principal = new ClaimsPrincipal(identity);
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
principal,
new AuthenticationProperties
{
IsPersistent = model.RememberMe
});
return RedirectToAction("Index", "Home");
}
}
return View(model);
}
2. JWT (JSON Web Token) 身份验证
原理:服务器生成包含用户信息的 JSON 令牌,客户端存储并在请求头中发送此令牌。服务器验证令牌签名和有效期来确认用户身份。
实现代码:
// Startup.cs 配置
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = Configuration["Jwt:Issuer"],
ValidAudience = Configuration["Jwt:Audience"],
IssuerSigningKey = new SymmetricSecurityKey(
Encoding.UTF8.GetBytes(Configuration["Jwt:SecretKey"]))
};
});
// 生成 Token
public string GenerateJwtToken(User user)
{
var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:SecretKey"]));
var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
var claims = new[]
{
new Claim(JwtRegisteredClaimNames.Sub, user.Username),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim(ClaimTypes.Role, user.Role)
};
var token = new JwtSecurityToken(
issuer: _config[