.NET 8新增认证端点无登录Token返回及端点类型问题咨询
.NET 8 Web API 认证端点问题解答
1. 让登录接口返回Bearer Token的实现方案
当前你的配置默认使用Cookie认证方案(Identity.Bearer),而AddApiEndpoints提供的默认登录端点是基于Cookie设计的,所以验证成功后仅返回200 OK,不会生成JWT。要返回Bearer Token,推荐通过自定义登录端点实现,步骤如下:
步骤1:添加JWT配置与生成服务
首先定义JWT参数模型和Token生成服务,用于生成符合要求的JWT:
// JWT参数模型 public class JwtSettings { public string SecretKey { get; set; } public string Issuer { get; set; } public string Audience { get; set; } public int ExpiresInMinutes { get; set; } } // JWT Token生成服务 public class JwtTokenService { private readonly JwtSettings _jwtSettings; private readonly UserManager<ApplicationUser> _userManager; public JwtTokenService(JwtSettings jwtSettings, UserManager<ApplicationUser> userManager) { _jwtSettings = jwtSettings; _userManager = userManager; } public async Task<string> GenerateTokenAsync(ApplicationUser user) { // 构建用户声明 var claims = new List<Claim> { new Claim(JwtRegisteredClaimNames.Sub, user.Id), new Claim(JwtRegisteredClaimNames.Email, user.Email!), new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()) }; // 添加用户角色声明 var roles = await _userManager.GetRolesAsync(user); claims.AddRange(roles.Select(r => new Claim(ClaimTypes.Role, r))); // 生成签名密钥 var signingKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtSettings.SecretKey)); var signingCreds = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256); // 构建JWT Token var token = new JwtSecurityToken( issuer: _jwtSettings.Issuer, audience: _jwtSettings.Audience, claims: claims, expires: DateTime.UtcNow.AddMinutes(_jwtSettings.ExpiresInMinutes), signingCredentials: signingCreds); return new JwtSecurityTokenHandler().WriteToken(token); } }
步骤2:注册JWT配置与服务
在Program.cs中注册JWT参数和生成服务(建议从appsettings.json读取配置,示例中暂用硬编码):
// 配置JWT参数 var jwtSettings = new JwtSettings { SecretKey = "your-strong-secret-key-min-16-chars", Issuer = "https://localhost:5000", Audience = "client.mydomain.com", ExpiresInMinutes = 60 }; builder.Services.AddSingleton(jwtSettings); // 注册Token生成服务 builder.Services.AddScoped<JwtTokenService>();
步骤3:调整认证方案默认配置
将默认认证方案改为JWT,确保后续接口验证使用Bearer Token:
builder.Services.AddAuthentication(options => { options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer("bearer", options => { options.Authority = "https://localhost:5000"; options.Audience = "client.mydomain.com"; options.RequireHttpsMetadata = true; options.SaveToken = true; options.IncludeErrorDetails = true; // 如果不依赖IdentityServer,手动配置Token验证参数 options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidIssuer = jwtSettings.Issuer, ValidateAudience = true, ValidAudience = jwtSettings.Audience, ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings.SecretKey)), ClockSkew = TimeSpan.Zero }; });
步骤4:添加自定义登录端点
替换默认的Cookie登录端点,实现返回JWT的逻辑:
// 登录请求模型 public class LoginRequest { [Required] public string Email { get; set; } [Required] public string Password { get; set; } } // 自定义登录端点 app.MapPost("/api/auth/login", async (LoginRequest request, UserManager<ApplicationUser> userManager, JwtTokenService tokenService) => { var user = await userManager.FindByEmailAsync(request.Email); if (user == null || !await userManager.CheckPasswordAsync(user, request.Password)) { return Results.Unauthorized(); } var accessToken = await tokenService.GenerateTokenAsync(user); return Results.Ok(new { AccessToken = accessToken, TokenType = "Bearer", ExpiresIn = jwtSettings.ExpiresInMinutes * 60 }); }) .WithName("ApiLogin") .WithOpenApi();
完成上述配置后,调用该端点验证成功会返回包含AccessToken的JSON响应,可直接复制到Swagger的授权框中使用。
2. 生成GET和POST两种登录端点的原因
AddApiEndpoints(即MapIdentityApi<ApplicationUser>)添加的两个登录端点是.NET 8 Identity API的默认设计,分工不同:
- GET /account/login:用于处理认证挑战场景。在Cookie认证模式下,当未认证用户访问受保护资源时,会重定向到该端点(返回登录页面);对于API场景,该端点通常返回401 Unauthorized,提示用户需要认证。
- POST /account/login:是实际接收用户邮箱/密码、执行登录验证的端点,默认验证成功后会设置Cookie(符合传统Web应用的认证流程)。
这种设计是为了同时兼容传统Cookie认证的Web应用场景和API场景,但默认实现更偏向Web应用,因此需要我们自定义逻辑来适配JWT认证的API需求。
内容的提问来源于stack exchange,提问作者dotnetdevcsharp
相关产品推荐
相关产品推荐

