You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用SQL Server身份验证实现ASP.NET Web API身份认证

完全可行!以下是具体配置步骤

1. 移除原有Windows身份验证配置

首先得把之前的Windows身份验证相关设置清理掉:

  • 替换控制器/方法上的[Authorize(Users = "\\")]为普通的[Authorize](后续我们会用新的认证逻辑来保护接口)
  • 根据你的.NET版本调整项目配置:
    • .NET Core/.NET 6+:在Program.cs里移除原来的Windows身份验证注册代码(比如AddAuthentication(IISDefaults.AuthenticationScheme)),确保启用匿名认证(因为我们要自己处理登录逻辑)
    • .NET Framework:在web.config中关闭Windows身份验证,启用匿名身份验证

2. 在SQL Server中创建用户存储表

你需要一个表来存储API用户的账号信息(绝对不要存明文密码!),示例SQL脚本如下:

CREATE TABLE ApiUsers (
    Id INT PRIMARY KEY IDENTITY(1,1),
    Username NVARCHAR(50) UNIQUE NOT NULL,
    PasswordHash NVARCHAR(256) NOT NULL, -- 存储密码的哈希值
    Email NVARCHAR(100) NULL
)

插入测试用户时,记得用加盐哈希算法(比如BCrypt)生成密码哈希,示例代码(C#):

// 生成密码哈希(比如给用户"testuser"的密码"TestPass123"生成哈希)
var passwordHash = BCrypt.Net.BCrypt.HashPassword("TestPass123");

3. 实现认证逻辑(推荐用JWT,API场景最常用)

这里以.NET 6+为例,分步骤配置:

3.1 添加必要的NuGet包

安装Microsoft.AspNetCore.Authentication.JwtBearer和BCrypt.Net-Next(用于密码哈希验证)

3.2 配置JWT参数

在appsettings.json中添加JWT的配置项:

"JwtSettings": {
    "SecretKey": "your_strong_random_secret_key_here_min_16_chars",
    "Issuer": "YourApiIssuerName",
    "Audience": "YourApiAudienceName",
    "ExpiresInMinutes": 60
}

⚠️ 注意:SecretKey一定要足够长且随机,不要硬编码在代码里,生产环境建议用环境变量或配置中心存储

3.3 注册JWT认证服务

在Program.cs中添加认证和授权服务:

var jwtSettings = builder.Configuration.GetSection("JwtSettings");

// 注册JWT认证
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ValidIssuer = jwtSettings["Issuer"],
            ValidAudience = jwtSettings["Audience"],
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings["SecretKey"]))
        };
    });

// 注册授权服务
builder.Services.AddAuthorization();

// 别忘了添加这两行,启用认证和授权中间件
app.UseAuthentication();
app.UseAuthorization();

3.4 编写登录接口

创建一个允许匿名访问的登录接口,用来验证SQL里的用户并返回JWT令牌:

[ApiController]
[Route("api/[controller]")]
public class AuthController : ControllerBase
{
    private readonly ApiDbContext _dbContext;
    private readonly IConfiguration _configuration;

    public AuthController(ApiDbContext dbContext, IConfiguration configuration)
    {
        _dbContext = dbContext;
        _configuration = configuration;
    }

    [AllowAnonymous]
    [HttpPost("login")]
    public async Task<IActionResult> Login([FromBody] LoginRequest model)
    {
        // 从SQL查询用户
        var user = await _dbContext.ApiUsers
            .FirstOrDefaultAsync(u => u.Username.Equals(model.Username, StringComparison.OrdinalIgnoreCase));

        // 验证用户和密码
        if (user == null || !BCrypt.Net.BCrypt.Verify(model.Password, user.PasswordHash))
        {
            return Unauthorized("用户名或密码错误");
        }

        // 生成JWT令牌
        var token = GenerateJwtToken(user);
        return Ok(new { AccessToken = token });
    }

    // 生成JWT令牌的辅助方法
    private string GenerateJwtToken(ApiUser user)
    {
        var jwtSettings = _configuration.GetSection("JwtSettings");
        var claims = new List<Claim>
        {
            new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
            new Claim(ClaimTypes.Name, user.Username)
        };

        var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings["SecretKey"]));
        var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

        var token = new JwtSecurityToken(
            issuer: jwtSettings["Issuer"],
            audience: jwtSettings["Audience"],
            claims: claims,
            expires: DateTime.UtcNow.AddMinutes(Convert.ToDouble(jwtSettings["ExpiresInMinutes"])),
            signingCredentials: creds);

        return new JwtSecurityTokenHandler().WriteToken(token);
    }
}

// 登录请求模型
public class LoginRequest
{
    public string Username { get; set; }
    public string Password { get; set; }
}

4. 保护API接口

在需要认证才能访问的控制器或方法上添加[Authorize]特性即可,比如:

[ApiController]
[Route("api/[controller]")]
[Authorize]
public class DataController : ControllerBase
{
    // 你的接口逻辑,只有携带有效JWT令牌的请求才能访问
    [HttpGet]
    public IActionResult GetData()
    {
        return Ok("这是需要认证才能访问的数据");
    }
}

5. 测试认证流程

  1. 调用POST /api/auth/login接口,传入正确的用户名和密码,获取返回的AccessToken
  2. 在后续请求的Authorization请求头中添加Bearer {你的AccessToken},即可访问受保护的API接口

可选:简单场景用基本认证

如果你的API场景比较简单,也可以实现基本认证(直接在请求头里传编码后的用户名密码),步骤类似:

  • 自定义一个BasicAuthenticationHandler来验证请求头里的凭证
  • 在Program.cs中注册这个认证方案
  • 同样用[Authorize]保护接口

内容的提问来源于stack exchange,提问作者user3759018

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:48:32