为什么Authorize特性指向account/login?

编程语言 2026-07-10

我正在同一个解决方案中同时使用Identity与 JWT身份验证。

下面是我的Program类

builder.Services.AddIdentity<ApplicationUser, IdentityRole>()
                .AddEntityFrameworkStores<StoreIdentityDbContext>()
                .AddDefaultTokenProviders();

builder.Services.AddScoped<IAuthenticationServices, AuthenticationServices>();

builder.Services.AddAuthentication(options =>
    {
        options.DefaultAuthenticateScheme = IdentityConstants.ApplicationScheme;
        options.DefaultChallengeScheme = IdentityConstants.ApplicationScheme;
        options.DefaultSignInScheme = IdentityConstants.ApplicationScheme;
    }).AddJwtBearer(options =>
          {
              options.SaveToken = true;
              options.TokenValidationParameters = new TokenValidationParameters()
                  {
                      ValidateIssuer = true,
                      ValidateAudience = true,
                      ValidIssuer = builder.Configuration["JWTOptions:Issuer"],
                      ValidAudience = builder.Configuration["JWTOptions:Audience"],
                      IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["JWTOptions:SecretKey"]!))
                  };
    }).AddCookie(IdentityConstants.ApplicationScheme, options =>
          {
                options.LoginPath = "/Admin/Login";
          });

builder.Services.ConfigureApplicationCookie(options =>
            {
                options.LoginPath = "/Admin/Login"; // This MUST be here
                options.AccessDeniedPath = "/Admin/AccessDenied";
                options.Cookie.Name = "GymunityAuthCookie"; // Custom name helps debugging
            });

现在,在UI项目中,我有一个控制器,其动作方法如下:

[Authorize(AuthenticationSchemes = "Identity.Application")]
public async Task<IActionResult> Index()
{
    var productRepo = _unitOfWork.GetRepository<Product, int>();

    var queryParams = new ProductQueryParms();
    var specification = new ProductWithTypeAndBrandSpec(queryParams, true);

    var products = await productRepo.GetAllAsync(specification);

    var productsViewModel = products.Select(product => new ProductViewModel
            {
                Id = product.Id,
                Name = product.Name,
                Description = product.Description,
                PictureUrl = product.PictureUrl,
                Price = product.Price,
                BrandId = product.BrandId,
                TypeId = product.TypeId,
                Brand = product.ProductBrand,
                Type = product.ProductType
            });

    return View(productsViewModel);
}

在未登录的情况下,访问 products/index 的URL会把我重定向到 account/login

有什么原因吗?

我把Program类改成了这个

builder.Services.AddAuthentication(options =>
    {
        // Sets the default scheme for authenticating requests
        options.DefaultAuthenticateScheme = IdentityConstants.ApplicationScheme;
        options.DefaultChallengeScheme = IdentityConstants.ApplicationScheme;
    });

builder.Services.AddIdentity<ApplicationUser, IdentityRole>()
         .AddEntityFrameworkStores<StoreIdentityDbContext>()
         .AddDefaultTokenProviders();

builder.Services.ConfigureApplicationCookie(options =>
     {
         options.LoginPath = "/Admin/Login"; // This MUST be here
         options.AccessDeniedPath = "/Admin/AccessDenied";
         options.Cookie.Name = "GymunityAuthCookie"; // Custom name helps debugging

         options.Events.OnRedirectToLogin = context =>
         {
             context.Response.StatusCode = StatusCodes.Status401Unauthorized;
             return Task.CompletedTask;
         };
         options.Events.OnRedirectToAccessDenied = context =>
         {
             context.Response.StatusCode = StatusCodes.Status403Forbidden;
             return Task.CompletedTask;
         };
     });

builder.Services.AddScoped<IAuthenticationServices, AuthenticationServices>();

//builder.Services.AddAuthentication(options =>
//{
     //    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
     //    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
     //}).AddJwtBearer(options =>
     //{
     //    options.SaveToken = true;
     //    options.TokenValidationParameters = new TokenValidationParameters()
     //    {
     //        ValidateIssuer = true,
     //        ValidateAudience = true,
     //        ValidIssuer = builder.Configuration["JWTOptions:Issuer"],
     //        ValidAudience = builder.Configuration["JWTOptions:Audience"],
     //        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["JWTOptions:SecretKey"]!))
     //    };
     //});

但我仍然遇到同样的问题。

解决方案

你可能希望通过避免设置所有默认选项来简化配置。

下面是一个ASP.NET Core MVC应用程序的工作示例(.NET 8),在其中同时使用Identity和 Jwt,并覆盖了默认的重定向URL。

Program.cs

builder.Services
    .AddIdentity<ApplicationUser, IdentityRole>()
    // ...

builder.Services
    .AddAuthentication()
    .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
    {
        // ...
    });

builder.Services.ConfigureApplicationCookie(options => options.LoginPath = "/Admin/Login");

// for the sake of sample completeness...
builder.Services.AddAuthorization(options =>
{
    options.DefaultPolicy = new AuthorizationPolicyBuilder()
        .RequireAuthenticatedUser()
        .Build();
});

在控制器中

[Authorize(AuthenticationSchemes = "Identity.Application")]
// or [Authorize]
// or no attribute if .RequireAuthorization() is applied globally to all endpoints
[HttpGet]
public IActionResult Index()
{
    // ...
}
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章