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

如何为AspNet Core 3.0-preview React IdentityServer4项目添加授权?

为带IdentityServer4的ASP.NET Core React模板项目添加角色/策略授权

我刚好处理过类似的场景,针对你用dotnet new react --name myproject --auth Individual创建的带IdentityServer4的ASP.NET Core 3.0 Preview7项目,要实现[Authorize(Roles = "Administrator")]这类授权特性,得从IdentityServer资源配置、ASP.NET Core服务配置、角色初始化这几个关键环节入手,下面是详细的操作流程:

1. 配置IdentityServer的身份与API资源

IdentityServer4需要明确将角色声明纳入返回的Token中,否则API无法识别用户的角色信息。找到项目中的Config.cs文件(若模板默认未生成,可手动创建),修改以下方法:

1.1 添加角色身份资源

让IdentityServer支持角色声明的身份资源:

public static IEnumerable<IdentityResource> GetIdentityResources()
{
    return new List<IdentityResource>
    {
        new IdentityResources.OpenId(),
        new IdentityResources.Profile(),
        // 添加角色身份资源,指定声明类型为"role"
        new IdentityResource("roles", "用户角色", new List<string> { "role" })
    };
}

1.2 配置API资源接受角色声明

确保你的API资源允许接收角色声明:

public static IEnumerable<ApiResource> GetApiResources()
{
    return new List<ApiResource>
    {
        new ApiResource("myprojectAPI", "My Project API")
        {
            // 让API识别并接收role类型的声明
            UserClaims = { JwtClaimTypes.Role }
        }
    };
}

1.3 更新客户端请求范围

修改客户端配置,让客户端在请求Token时包含roles范围:

public static IEnumerable<Client> GetClients()
{
    return new List<Client>
    {
        new Client
        {
            ClientId = "myproject",
            ClientName = "myproject",
            AllowedGrantTypes = GrantTypes.Code,
            RequirePkce = true,
            RequireClientSecret = false,
            RedirectUris =           { "https://localhost:5001/authentication/login-callback" },
            PostLogoutRedirectUris = { "https://localhost:5001/" },
            AllowedCorsOrigins =     { "https://localhost:5001" },
            AllowedScopes =
            {
                IdentityServerConstants.StandardScopes.OpenId,
                IdentityServerConstants.StandardScopes.Profile,
                "myprojectAPI",
                // 新增roles范围
                "roles"
            },
            AllowOfflineAccess = true
        }
    };
}

2. 配置Startup.cs中的服务

调整Identity和授权服务的配置,确保角色支持生效:

2.1 启用Identity角色支持

替换模板默认的AddDefaultIdentity,改为完整的Identity配置以支持角色:

services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(
        Configuration.GetConnectionString("DefaultConnection")));

// 启用Identity用户与角色的EF存储支持
services.AddIdentity<IdentityUser, IdentityRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddDefaultTokenProviders()
    .AddDefaultUI();

2.2 配置IdentityServer集成

确保IdentityServer使用我们配置的资源,并关联Identity角色:

services.AddIdentityServer()
    .AddApiAuthorization<IdentityUser, ApplicationDbContext>(options =>
    {
        // 确保API资源包含role声明(若未使用Config.cs则需配置此项)
        options.ApiResources.Single().UserClaims.Add("role");
    })
    .AddIdentityResources()
    .AddClients()
    .AddAspNetIdentity<IdentityUser>();

2.3 配置授权策略

添加授权策略支持,既可以使用默认的角色授权,也可以自定义策略:

services.AddAuthorization(options =>
{
    // 自定义管理员策略(可选)
    options.AddPolicy("AdminOnly", policy => policy.RequireRole("Administrator"));
    // 默认的角色授权已自动支持,直接用[Authorize(Roles="Administrator")]即可
});

2.4 映射JWT角色声明类型

ASP.NET Core默认的角色声明类型与IdentityServer的默认值不同,需要手动映射确保识别:

services.AddAuthentication()
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            // 将JWT中的"role"声明映射为ASP.NET Core的角色声明
            RoleClaimType = JwtClaimTypes.Role
        };
    });

3. 初始化角色与测试用户

在项目启动时自动创建Administrator角色并分配给测试用户,方便验证:
在Program.cs的CreateHostBuilder方法末尾添加初始化逻辑:

var host = CreateHostBuilder(args).Build();

using (var scope = host.Services.CreateScope())
{
    var services = scope.ServiceProvider;
    try
    {
        var roleManager = services.GetRequiredService<RoleManager<IdentityRole>>();
        var userManager = services.GetRequiredService<UserManager<IdentityUser>>();

        // 创建Administrator角色
        if (!await roleManager.RoleExistsAsync("Administrator"))
        {
            var adminRole = new IdentityRole("Administrator");
            await roleManager.CreateAsync(adminRole);
        }

        // 创建测试管理员用户(可选)
        var adminUser = await userManager.FindByEmailAsync("admin@example.com");
        if (adminUser == null)
        {
            adminUser = new IdentityUser { UserName = "admin@example.com", Email = "admin@example.com" };
            await userManager.CreateAsync(adminUser, "Password123!");
            await userManager.AddToRoleAsync(adminUser, "Administrator");
        }
    }
    catch (Exception ex)
    {
        var logger = services.GetRequiredService<ILogger<Program>>();
        logger.LogError(ex, "初始化角色与用户时发生错误");
    }
}

host.Run();

4. 在控制器中使用授权特性

现在就可以在控制器方法上直接使用授权特性了:

[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
    [HttpGet]
    [Authorize(Roles = "Administrator")]
    public IEnumerable<WeatherForecast> Get()
    {
        // 仅管理员可访问的逻辑
        var rng = new Random();
        return Enumerable.Range(1, 5).Select(index => new WeatherForecast
        {
            Date = DateTime.Now.AddDays(index),
            TemperatureC = rng.Next(-20, 55),
            Summary = Summaries[rng.Next(Summaries.Length)]
        })
        .ToArray();
    }
}

内容的提问来源于stack exchange,提问作者Andreas Sjöberg

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:07:48