.NET 7中受保护控制器操作返回401错误而非跳转至登录页
问题:访问受保护页面返回401而非跳转登录页
我正在开发一个带有受保护区域的.NET 7 Web应用,单体架构拆分为多个程序集,程序集拆分运行正常,但实现受保护页面时遇到问题。
模块Startup类代码:
public class Startup : IModuleStartup { public void ConfigureServices(IServiceCollection services, IConfiguration configuration) { services.AddTransient<IPasswordHasher<ApplicationUser>, CustomPasswordHasher>(); services.AddTransient<IEmailSender, EmailSender>(); services.AddIdentity<ApplicationUser, ApplicationRole>(options => { options.SignIn.RequireConfirmedEmail = true; options.Stores.MaxLengthForKeys = 128; options.User.RequireUniqueEmail = true; }) .AddDefaultTokenProviders(); services.AddTransient<IUserStore<ApplicationUser>, CustomUserStore>(); services.AddTransient<IRoleStore<ApplicationRole>, CustomRoleStore>(); services.AddScoped<IAccountService, AccountService>(); services.AddScoped<IUsuarioService, UsuarioService>(); services.AddDbContext<SecuWebModulesAuthenticateContext>(options => { options .UseSqlServer(configuration.GetConnectionString("Modules.Authenticate")); #if DEBUG options.LogTo(x => Debug.WriteLine(x)); #endif }); // Agrega autenticación services.AddAuthentication() .AddCookie("Cookies", options => { options.LoginPath = "/Security/Login"; options.LogoutPath = "/Security/Logout"; options.AccessDeniedPath = "/Security/AccessDenied"; options.ReturnUrlParameter = "ReturnUrl"; }) .AddJwtBearer(x => { x.RequireHttpsMetadata = true; x.SaveToken = true; x.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidIssuer = configuration["Modules:Authenticate:AuthJwt:Issuer"], ValidateAudience = true, ValidAudience = configuration["Modules:Authenticate:AuthJwt:Audience"], ValidateIssuerSigningKey = true, RequireExpirationTime = false, ValidateLifetime = true, ClockSkew = TimeSpan.Zero, IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["Modules:Authenticate:AuthJwt:Key"] ?? string.Empty)) }; }); services.AddAuthorization(); } public void Configure(IApplicationBuilder app) { app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } }
控制器代码:
[Authorize] public class UsuarioController : Controller { public IActionResult Index() { return View(); } }
访问https://localhost:7255/Usuario时,页面返回401错误,而非跳转至登录页,缺少哪些配置?
解决方案
1. 设置默认认证方案
你同时添加了Cookie和JwtBearer两种认证方式,但未指定默认认证方案,框架无法确定用哪种方式处理未认证请求,导致直接返回401而非跳转登录页。修改AddAuthentication代码,指定默认方案为Cookie:
services.AddAuthentication("Cookies") // 指定默认认证方案为Cookie .AddCookie("Cookies", options => { options.LoginPath = "/Security/Login"; options.LogoutPath = "/Security/Logout"; options.AccessDeniedPath = "/Security/AccessDenied"; options.ReturnUrlParameter = "ReturnUrl"; }) // JwtBearer配置保持不变 .AddJwtBearer(x => { x.RequireHttpsMetadata = true; x.SaveToken = true; x.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidIssuer = configuration["Modules:Authenticate:AuthJwt:Issuer"], ValidateAudience = true, ValidAudience = configuration["Modules:Authenticate:AuthJwt:Audience"], ValidateIssuerSigningKey = true, RequireExpirationTime = false, ValidateLifetime = true, ClockSkew = TimeSpan.Zero, IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["Modules:Authenticate:AuthJwt:Key"] ?? string.Empty)) }; });
2. 确认中间件顺序与路由配置
确保认证/授权中间件的顺序正确,且添加MVC默认路由(如果使用视图):
public void Configure(IApplicationBuilder app) { // 静态文件中间件需在认证授权之前 app.UseStaticFiles(); // 路由中间件需在认证授权之前 app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); // 添加MVC默认路由,确保视图路由可被解析 endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); }); }
3. 验证登录页面路由有效性
确保/Security/Login对应的SecurityController及Login方法存在,且能正常返回视图,避免跳转后出现404错误。
内容的提问来源于stack exchange,提问作者jstuardo
相关产品推荐
相关产品推荐

