在ASP.NET Core/Blazor的ApiController中配置HTTP基本认证
解决ASP.NET Core API的HTTP基本认证实现问题
首先得纠正你现有代码里的错误:你在控制器构造函数里给HttpContext.Request.Headers添加Authorization头是搞反了逻辑——这是给服务器自己的请求对象加头,而我们需要验证客户端发送过来的请求头,不是给自己加。
下面分步骤给你讲正确的实现方式:
第一步:正确读取配置文件
不要在构造函数里手动构建ConfigurationBuilder,ASP.NET Core已经默认支持配置文件注入,只需确保appsettings_Authentication.json被加载:
- 在
Program.cs里添加配置加载代码:
builder.Configuration.AddJsonFile("appsettings_Authentication.json", optional: false, reloadOnChange: true);
- 修改控制器构造函数,通过依赖注入获取
IConfiguration:
private readonly IConfiguration _config; private readonly string _validUsername; private readonly string _validPassword; public ManagerPDF(Database DB, ManipulatorPDF manipulatorPDF, IConfiguration config) { // 保留你的其他业务代码 _config = config; _validUsername = _config.GetSection("AuthenticationHeader")["username"]; _validPassword = _config.GetSection("AuthenticationHeader")["password"]; }
第二步:实现认证验证逻辑(两种可选方案)
方案一:自定义Action过滤器(针对单个控制器/Action)
这种方式适合只给特定控制器加认证的场景:
- 创建自定义过滤器类:
public class BasicAuthFilter : IActionFilter { private readonly string _validUsername; private readonly string _validPassword; public BasicAuthFilter(string validUsername, string validPassword) { _validUsername = validUsername; _validPassword = validPassword; } public void OnActionExecuting(ActionExecutingContext context) { // 1. 检查请求头是否包含Authorization if (!context.HttpContext.Request.Headers.TryGetValue("Authorization", out var authHeader)) { context.Result = new UnauthorizedResult(); return; } var authValue = authHeader.ToString(); // 2. 检查是否是Basic认证格式 if (!authValue.StartsWith("Basic ", StringComparison.OrdinalIgnoreCase)) { context.Result = new UnauthorizedResult(); return; } // 3. 解码Base64格式的用户名密码 var base64Encoded = authValue.Substring("Basic ".Length).Trim(); var bytes = Convert.FromBase64String(base64Encoded); var credentials = Encoding.UTF8.GetString(bytes).Split(':', 2); // 4. 验证用户名密码是否匹配 if (credentials.Length != 2 || credentials[0] != _validUsername || credentials[1] != _validPassword) { context.Result = new UnauthorizedResult(); return; } // 验证通过,继续执行控制器Action } public void OnActionExecuted(ActionExecutedContext context) { } }
- 在控制器上应用过滤器:
如果你用依赖注入注册过滤器(推荐):
在Program.cs里注册:
然后控制器上加特性:builder.Services.AddScoped<BasicAuthFilter>(sp => { var config = sp.GetRequiredService<IConfiguration>(); var username = config.GetSection("AuthenticationHeader")["username"]; var password = config.GetSection("AuthenticationHeader")["password"]; return new BasicAuthFilter(username, password); });[ApiController] [Route("PDF/[controller]")] [ServiceFilter(typeof(BasicAuthFilter))] public class ManagerPDF : ControllerBase { // 你的控制器代码 }
方案二:使用ASP.NET Core自带的Basic认证(推荐生产环境)
这种方式更符合框架的认证授权体系,扩展性更强:
- 安装NuGet包:
Microsoft.AspNetCore.Authentication.Basic - 在
Program.cs里配置认证和授权:
// 配置Basic认证 builder.Services.AddAuthentication("Basic") .AddBasic(options => { options.Events = new BasicAuthenticationEvents { OnValidateCredentials = async context => { var config = context.HttpContext.RequestServices.GetRequiredService<IConfiguration>(); var validUsername = config.GetSection("AuthenticationHeader")["username"]; var validPassword = config.GetSection("AuthenticationHeader")["password"]; if (context.Username == validUsername && context.Password == validPassword) { // 验证通过,创建用户身份 context.Principal = new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim(ClaimTypes.Name, context.Username) }, "Basic")); context.Success(); } } }; }); // 添加授权服务 builder.Services.AddAuthorization(); // 中间件管道里要加这两个,顺序不能错 app.UseAuthentication(); app.UseAuthorization();
- 在控制器上加
[Authorize]特性:
[ApiController] [Route("PDF/[controller]")] [Authorize(AuthenticationSchemes = "Basic")] public class ManagerPDF : ControllerBase { // 你的控制器代码 }
注意事项
- HTTP基本认证的Base64编码是可逆的,必须用HTTPS传输,否则用户名密码会被轻易解码。
- 如果验证失败,框架或过滤器会自动返回401 Unauthorized响应,不需要手动处理。
内容的提问来源于stack exchange,提问作者Saucter
相关产品推荐
相关产品推荐

