MVC项目调用API认证报错:未指定AuthenticationScheme
问题原因
你遇到的错误是因为MVC项目未配置JWT认证方案,也未设置默认挑战方案,导致[Authorize]特性生效时,框架不知道该用哪种方式验证身份、发起挑战。
解决方案
1. 安装必要NuGet包
确保MVC项目安装Microsoft.AspNetCore.Authentication.JwtBearer包,可通过NuGet包管理器或命令行执行:
Install-Package Microsoft.AspNetCore.Authentication.JwtBearer
2. 配置认证服务
根据你的.NET版本,在服务配置中添加JWT认证并设置默认方案:
.NET 6+(Program.cs)
var builder = WebApplication.CreateBuilder(args); // 添加MVC服务 builder.Services.AddControllersWithViews(); // 添加Session支持(用于存储token) builder.Services.AddSession(); // 配置JWT认证 builder.Services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(options => { // 配置需与API项目的JWT参数完全一致 options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = builder.Configuration["Jwt:Issuer"], ValidAudience = builder.Configuration["Jwt:Audience"], IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"])) }; // 从Session中读取token(替代默认的请求头读取方式) options.Events = new JwtBearerEvents { OnMessageReceived = context => { var token = context.HttpContext.Session.GetString("JWToken"); if (!string.IsNullOrEmpty(token)) { context.Token = token; } return Task.CompletedTask; } }; }); var app = builder.Build(); // 中间件顺序不能错:Session → 认证 → 授权 app.UseSession(); app.UseAuthentication(); app.UseAuthorization(); app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); app.Run();
.NET 5及以下(Startup.cs)
在ConfigureServices方法中添加:
public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); services.AddSession(); services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = Configuration["Jwt:Issuer"], ValidAudience = Configuration["Jwt:Audience"], IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"])) }; options.Events = new JwtBearerEvents { OnMessageReceived = context => { var token = context.HttpContext.Session.GetString("JWToken"); if (!string.IsNullOrEmpty(token)) { context.Token = token; } return Task.CompletedTask; } }; }); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { // 其他中间件(如异常处理、静态文件等)... app.UseSession(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); }); }
3. 优化登录逻辑(可选)
API返回的token可能带首尾引号,需先处理为纯token字符串:
string token = await response.Content.ReadAsStringAsync(); // 去除首尾引号 token = token.Trim('"');
4. 配置文件同步JWT参数
在MVC项目的appsettings.json中添加与API一致的JWT配置:
{ "Jwt": { "Issuer": "你的API颁发者", "Audience": "你的API受众", "Key": "你的签名密钥(与API完全相同)" } }
关键注意事项
- 中间件顺序必须严格遵循:
UseSession()→UseAuthentication()→UseAuthorization(),顺序错误会导致认证失败。 - JWT的所有配置参数必须与API项目完全一致,否则会出现token验证失败。
内容的提问来源于stack exchange,提问作者Jéssica Galhardi
相关产品推荐
相关产品推荐

