公司动态

.NET CORE 认证模块-注册方案与请求认证探究

📅 2026/7/27 20:18:51
.NET CORE 认证模块-注册方案与请求认证探究
.NET CORE 认证模块-注册方案与请求认证探究一、认证模块的基础认知在 .NET Core 中认证模块是一个核心的安全组件它负责验证用户的身份。认证过程包括两个关键阶段注册方案和请求认证。注册方案定义了认证的方式如 Cookie、JWT 等而请求认证则是在每次 HTTP 请求中验证用户的身份。首先我们需要理解几个核心概念-AuthenticationHandler认证处理器负责具体的认证逻辑-AuthenticationScheme认证方案定义了认证的名称和类型-AuthenticationMiddleware认证中间件处理 HTTP 请求中的认证流程## 二、注册方案从基础开始注册方案是认证模块的起点。在Startup.cs的ConfigureServices方法中我们可以注册各种认证方案。最简单的例子是使用 Cookie 认证。### 基础 Cookie 认证注册csharp// 在 Startup.cs 的 ConfigureServices 方法中public void ConfigureServices(IServiceCollection services){ // 添加认证服务并注册默认的 Cookie 方案 services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie(options { // 设置登录路径当用户未认证时重定向到此路径 options.LoginPath /Account/Login; // 设置 Cookie 名称 options.Cookie.Name MyAppCookie; // 设置 Cookie 过期时间 options.ExpireTimeSpan TimeSpan.FromHours(1); }); services.AddControllersWithViews();}这段代码做了以下事情1.AddAuthentication()注册认证服务并指定默认方案为 Cookie2.AddCookie()注册 Cookie 方案并配置选项3. 配置登录路径和 Cookie 行为## 三、请求认证中间件的作用注册方案后我们需要在请求管道中使用认证中间件。在Configure方法中我们添加认证中间件来处理每个请求。### 请求认证配置csharp// 在 Startup.cs 的 Configure 方法中public void Configure(IApplicationBuilder app, IWebHostEnvironment env){ if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler(/Home/Error); } app.UseStaticFiles(); // 添加认证中间件 - 顺序很重要必须在 UseAuthorization 之前 app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints { endpoints.MapControllerRoute( name: default, pattern: {controllerHome}/{actionIndex}/{id?}); });}关键点-UseAuthentication()必须放在UseAuthorization()之前- 中间件的顺序决定了请求处理的流程## 四、深入探究自定义认证方案当标准方案不满足需求时我们可以创建自定义认证方案。下面是一个完整的示例展示如何创建基于 API Key 的认证方案。### 自定义认证处理器实现csharp// 自定义认证方案类public class ApiKeyAuthenticationHandler : AuthenticationHandlerApiKeyAuthenticationOptions{ private readonly IConfiguration _configuration; public ApiKeyAuthenticationHandler( IOptionsMonitorApiKeyAuthenticationOptions options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock, IConfiguration configuration) : base(options, logger, encoder, clock) { _configuration configuration; } protected override async TaskAuthenticateResult HandleAuthenticateAsync() { // 从请求头中获取 API Key if (!Request.Headers.TryGetValue(X-API-Key, out var apiKeyHeaderValues)) { // 如果没有 API Key返回认证失败 return AuthenticateResult.Fail(Missing API Key); } var providedApiKey apiKeyHeaderValues.FirstOrDefault(); if (string.IsNullOrEmpty(providedApiKey)) { return AuthenticateResult.Fail(Invalid API Key); } // 验证 API Key 是否有效这里简单地与配置文件中的值比较 var validApiKey _configuration[ApiKey]; if (!string.Equals(providedApiKey, validApiKey, StringComparison.Ordinal)) { return AuthenticateResult.Fail(Invalid API Key); } // 创建 Claims 和身份标识 var claims new[] { new Claim(ClaimTypes.Name, API User), new Claim(ClaimTypes.Role, ApiClient), new Claim(ApiKey, providedApiKey) }; var identity new ClaimsIdentity(claims, Scheme.Name); var principal new ClaimsPrincipal(identity); var ticket new AuthenticationTicket(principal, Scheme.Name); // 返回认证成功结果 return AuthenticateResult.Success(ticket); }}### 自定义认证选项类csharp// 自定义认证选项public class ApiKeyAuthenticationOptions : AuthenticationSchemeOptions{ public const string DefaultScheme ApiKey; public string Scheme DefaultScheme;}### 在 Startup 中注册自定义方案csharp// 在 ConfigureServices 方法中public void ConfigureServices(IServiceCollection services){ // 注册自定义 API Key 认证方案 services.AddAuthentication(ApiKeyAuthenticationOptions.DefaultScheme) .AddSchemeApiKeyAuthenticationOptions, ApiKeyAuthenticationHandler( ApiKeyAuthenticationOptions.DefaultScheme, options { }); services.AddControllers();}## 五、高级应用多方案认证与策略在实际项目中我们可能需要支持多种认证方式。.NET Core 支持多方案认证并允许通过策略进行细粒度控制。### 多方案认证配置csharppublic void ConfigureServices(IServiceCollection services){ services.AddAuthentication() .AddCookie(CookieAuth, options { options.LoginPath /Account/Login; options.Cookie.Name MyAppCookie; }) .AddJwtBearer(Bearer, options { options.TokenValidationParameters new TokenValidationParameters { ValidateIssuer true, ValidIssuer https://myapp.com, ValidateAudience true, ValidAudience https://myapp.com, ValidateLifetime true, IssuerSigningKey new SymmetricSecurityKey( Encoding.UTF8.GetBytes(my-secret-key-here)) }; }); // 定义认证策略 services.AddAuthorization(options { // 策略1只能通过 Cookie 认证 options.AddPolicy(CookieOnly, policy { policy.AuthenticationSchemes.Add(CookieAuth); policy.RequireAuthenticatedUser(); }); // 策略2Cookie 或 JWT 都可以 options.AddPolicy(Mixed, policy { policy.AuthenticationSchemes.Add(CookieAuth); policy.AuthenticationSchemes.Add(Bearer); policy.RequireAuthenticatedUser(); }); }); services.AddControllers();}### 在控制器中使用策略csharp[ApiController][Route(api/[controller])]public class SecureController : ControllerBase{ // 使用默认认证方案 [HttpGet(public-data)] [Authorize] public IActionResult GetPublicData() { return Ok(This is public data); } // 使用 Cookie 认证策略 [HttpGet(cookie-data)] [Authorize(Policy CookieOnly)] public IActionResult GetCookieData() { return Ok(This requires Cookie authentication); } // 使用混合认证策略 [HttpGet(mixed-data)] [Authorize(Policy Mixed)] public IActionResult GetMixedData() { return Ok(This accepts both Cookie and JWT); }}## 六、性能优化与最佳实践### 认证缓存优化对于频繁的 API 请求我们可以缓存认证结果以提高性能csharppublic class CachedAuthenticationHandler : AuthenticationHandlerAuthenticationSchemeOptions{ private readonly IMemoryCache _cache; public CachedAuthenticationHandler( IOptionsMonitorAuthenticationSchemeOptions options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock, IMemoryCache cache) : base(options, logger, encoder, clock) { _cache cache; } protected override async TaskAuthenticateResult HandleAuthenticateAsync() { var token Request.Headers[Authorization].FirstOrDefault(); if (string.IsNullOrEmpty(token)) return AuthenticateResult.Fail(No token); // 尝试从缓存获取认证结果 var cacheKey $auth_{token}; if (_cache.TryGetValue(cacheKey, out AuthenticateResult cachedResult)) { return cachedResult; } // 执行实际的认证逻辑 var result await PerformAuthenticationAsync(token); // 缓存认证结果设置过期时间 if (result.Succeeded) { _cache.Set(cacheKey, result, TimeSpan.FromMinutes(5)); } return result; } private TaskAuthenticateResult PerformAuthenticationAsync(string token) { // 实际的认证逻辑 return Task.FromResult(AuthenticateResult.Fail(Not implemented)); }}## 总结通过本文的探究我们深入理解了 .NET Core 认证模块的核心机制。从基础的 Cookie 认证注册到请求认证中间件的配置再到自定义认证方案的实现每一步都揭示了认证模块的灵活性和可扩展性。关键要点1.注册方案是认证的起点通过AddAuthentication和AddCookie/AddJwtBearer等方法配置2.请求认证通过UseAuthentication中间件实现顺序至关重要3.自定义方案允许我们根据业务需求创建独特的认证逻辑4.多方案与策略提供了细粒度的访问控制能力5.性能优化如缓存认证结果可以提升系统响应速度在实际开发中应根据应用场景选择合适的认证方案并注意安全性和性能的平衡。掌握这些知识将帮助你在 .NET Core 应用中构建安全、高效的认证系统。