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

ASP.NET Core Web API基于角色的授权策略无法生效问题求助

问题根因

你遇到的[Authorize(Policy = "readpolicy")]不生效的问题,主要来自三个核心错误:

  • 中间件顺序错误,UseHttpsRedirection放在了身份验证/授权中间件之后,跳转时丢失了认证上下文
  • 认证配置冲突,同时混用了Jwt和Cookie两种认证逻辑,AddDefaultIdentity默认自带Cookie认证,覆盖了你之前设置的Jwt默认方案,且你登录时用的SignInAsync是Cookie认证专属逻辑,和Jwt无状态认证的逻辑完全不匹配
  • 存在大量冗余配置,干扰了授权逻辑的正常执行
修复步骤

1. 移除所有冗余配置

你是前后端分离的Web API,用Jwt做认证,以下代码完全不需要,可以直接删除:

  • 自己手动构建的IConfigurationRoot configuration,WebApplication.CreateBuilder已经默认加载了appsettings.json、环境变量、环境专属配置文件,直接用builder.Configuration即可
  • 所有Cookie相关配置:CookiePolicyOptions配置、AddCookie()注册、UseCookiePolicy()中间件
  • AddDefaultIdentity,你不需要Identity自带的登录页、Cookie认证等逻辑,换成更轻量的AddIdentityCore即可,避免覆盖Jwt默认配置

2. 修正中间件顺序

正确的中间件执行顺序必须是:UseHttpsRedirection → UseRouting → UseAuthentication → UseAuthorization → 端点映射

3. 修正Jwt配置与登录逻辑

  • 在你的ConfigureJwtBearerOptions类中,确保TokenValidationParameters的RoleClaimType设置为ClaimTypes.Role,保证授权时能正确识别角色声明
  • 废弃当前的HttpContext.SignInAsync登录逻辑:Jwt是无状态认证,不需要服务端保存登录状态,你需要在验证完谷歌登录的payload后,生成Jwt Token返回给React前端,前端后续所有请求在请求头携带Authorization: Bearer <生成的Jwt Token>即可
梳理后的完整Program.cs代码
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using WTSS_Portal_Middleware.Data;

var builder = WebApplication.CreateBuilder(args);

// 注册数据库上下文
builder.Services.AddDbContext<TSTWTSSPortalContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
builder.Services.AddDbContext<UserDbContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("UserDbConnection")));

// 注册核心Identity服务,仅用角色、用户管理功能,不加载默认Cookie/页面逻辑
builder.Services.AddIdentityCore<IdentityUser>()
    .AddRoles<IdentityRole>()
    .AddEntityFrameworkStores<UserDbContext>();

// 注册JWT认证
builder.Services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer();
builder.Services.AddTransient<IConfigureOptions<JwtBearerOptions>, ConfigureJwtBearerOptions>();

// 注册授权策略
builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("readpolicy",
        policy => policy.RequireRole("WTSS support", "System owner", "Regular user", "Company owner", "Unauthenticated"));
    options.AddPolicy("writepolicy",
        policy => policy.RequireRole("WTSS support", "System owner"));
});

// 注册基础服务
builder.Services.AddControllers();
builder.Services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new() { Title = "WTSS_Portal_Middleware", Version = "v1" });
});

var app = builder.Build();

// 配置中间件管道
if (app.Environment.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
    app.UseSwagger();
    app.UseSwaggerUI(c =>
    {
        c.SwaggerEndpoint("/swagger/v1/swagger.json", "WTSS_Portal_Middleware V1");
        c.RoutePrefix = string.Empty;
    });
}

// 注意顺序不能乱
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();

app.Run();
补充说明

你之前[Authorize]生效但带Policy的不生效的原因是:[Authorize]只校验请求是否经过认证,不校验角色权限,所以只要Jwt或者Cookie任意一种认证通过就可以访问,而带Policy的校验需要正确读取到请求中的角色声明,因为之前的配置冲突,角色声明没有被授权逻辑正确识别,所以校验失败无法命中接口。

内容的提问来源于stack exchange,提问作者congying pan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 02:09:04