.NET Core 基于声明的身份验证与存储方法

在 .NET Core 中,基于声明的身份验证(Claims-based Authentication) 是一种将用户身份信息抽象为一系列可验证的声明(Claims)的认证模型。与传统基于角色的身份验证相比,它提供了更细粒度的权限控制和灵活性。


1. 基于声明的身份验证(Claims-based Authentication)

核心概念
  • 声明(Claim):一个键值对,描述用户的某个属性(如 Email = "user@example.com"Role = "Admin")。
  • 身份(Identity):由一组声明构成,代表一个用户的身份(如 ClaimsIdentity)。
  • 主体(Principal):包含一个或多个身份的对象(如 ClaimsPrincipal),表示当前请求的上下文用户。
工作流程
  1. 用户登录时,系统验证凭证(如用户名密码)。
  2. 验证成功后,生成一组声明(如用户ID、角色、邮箱等)。
  3. 声明被封装到 ClaimsPrincipal 中,附加到当前请求的 HttpContext.User
  4. 后续请求通过检查声明来授权访问。
示例代码:创建声明
var claims = new List<Claim>
{
    new Claim(ClaimTypes.Name, "Alice"),
    new Claim(ClaimTypes.Email, "alice@example.com"),
    new Claim("Department", "HR")
};

var identity = new ClaimsIdentity(claims, "CustomAuth");
var principal = new ClaimsPrincipal(identity);

await HttpContext.SignInAsync("CookieAuthScheme", principal);

2. 存储用户信息的方式

在 .NET Core 中,用户信息通常通过以下方式存储:


方式 1:使用 ASP.NET Core Identity

ASP.NET Core Identity 是官方提供的用户管理系统,内置用户信息存储、密码哈希、角色管理等功能。

步骤
  1. 安装 NuGet 包
Install-Package Microsoft.AspNetCore.Identity.EntityFrameworkCore
  1. 定义用户模型(可扩展):
public class ApplicationUser : IdentityUser
{
    public string CustomProperty { get; set; }
}
  1. 配置数据库上下文
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options) { }
}
  1. 注册 Identity 服务(在 Startup.cs):
services.AddIdentity<ApplicationUser, IdentityRole>()
        .AddEntityFrameworkStores<ApplicationDbContext>()
        .AddDefaultTokenProviders();
  1. 迁移数据库
dotnet ef migrations add InitialCreate
dotnet ef database update

方式 2:自定义存储

如果不想使用 Identity,可以直接操作声明或使用其他存储方式(如数据库、外部 API)。

示例:手动存储声明到 Cookie
var claims = new List<Claim>
{
    new Claim(ClaimTypes.Name, "Bob"),
    new Claim("UserAge", "30")
};

var claimsIdentity = new ClaimsIdentity(claims, "CustomAuthType");
var authProperties = new AuthenticationProperties
{
    IsPersistent = true // 持久化 Cookie
};

await HttpContext.SignInAsync(
    "CustomScheme",
    new ClaimsPrincipal(claimsIdentity),
    authProperties
);
示例:从数据库加载用户信息
public async Task<ClaimsPrincipal> CreatePrincipalAsync(string username)
{
    var user = await _userRepository.FindByUsernameAsync(username);
    var claims = new List<Claim>
    {
        new Claim(ClaimTypes.Name, user.Username),
        new Claim(ClaimTypes.Email, user.Email)
    };
    return new ClaimsPrincipal(new ClaimsIdentity(claims, "CustomAuth"));
}

方式 3:使用 JWT(用于 API)

在 Web API 中,用户信息可通过 JWT(JSON Web Token)存储并在请求头中传递。

  1. 生成 JWT
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("your-secret-key"));
var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

var claims = new[]
{
    new Claim(JwtRegisteredClaimNames.Sub, "user1"),
    new Claim(JwtRegisteredClaimNames.Email, "user1@example.com")
};

var token = new JwtSecurityToken(
    issuer: "your-issuer",
    audience: "your-audience",
    claims: claims,
    expires: DateTime.Now.AddHours(1),
    signingCredentials: credentials
);

var jwt = new JwtSecurityTokenHandler().WriteToken(token);
  1. 验证 JWT(在 Startup.cs):
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(options =>
        {
            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuer = true,
                ValidateAudience = true,
                ValidIssuer = "your-issuer",
                ValidAudience = "your-audience",
                IssuerSigningKey = new SymmetricSecurityKey(
                    Encoding.UTF8.GetBytes("your-secret-key"))
            };
        });

3. 关键注意事项

  • 敏感数据:避免在声明中存储密码等敏感信息。
  • 加密:使用 HTTPS 保护 Cookie 或 JWT。
  • 声明大小:Cookie 有大小限制(通常 4096 字节),JWT 适合存储精简信息。

通过合理选择存储方式,可以灵活管理用户信息并实现安全的身份验证。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Gene Z

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值