You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 05:14:55