如何为ASP.NET Core Web API添加读写权限控制
解决方案
一、基于Scope的权限控制
1. 在Azure AD中定义API权限
- 进入Azure Portal的应用注册,找到你的API应用,打开「公开API」页面
- 添加两个自定义Scope:
api.read(对应只读权限)、api.write(对应写入权限) - 切换到获取token的客户端应用,在「API权限」页面添加上述两个Scope,并完成管理员同意
2. 调整API代码配置
在添加身份验证服务时,配置JWT验证逻辑,并定义授权策略:
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"), options => { // 指定验证参数,确保受众匹配 options.TokenValidationParameters.ValidAudience = builder.Configuration["AzureAd:Audience"]; }); // 定义授权策略 builder.Services.AddAuthorization(options => { options.AddPolicy("RequireReadScope", policy => policy.RequireClaim("scp", "api.read")); options.AddPolicy("RequireWriteScope", policy => policy.RequireClaim("scp", "api.write")); });
3. 在控制器方法上应用权限控制
在需要限制的Action上添加对应策略:
[ApiController] [Route("api/[controller]")] [Authorize] public class DataController : ControllerBase { // 只读接口,仅允许携带api.read Scope的token访问 [HttpGet] [Authorize(Policy = "RequireReadScope")] public IActionResult GetData() { return Ok("只读数据"); } // 写入接口,仅允许携带api.write Scope的token访问 [HttpPost] [Authorize(Policy = "RequireWriteScope")] public IActionResult PostData([FromBody] string data) { return Ok($"已写入数据:{data}"); } }
4. 获取指定Scope的Token
调用token接口时,修改scope参数为对应权限:
- 只读请求:
scope=https://example.onmicrosoft.com/my_client_id/api.read - 写入请求:
scope=https://example.onmicrosoft.com/my_client_id/api.write - 同时需要两种权限:
scope=https://example.onmicrosoft.com/my_client_id/api.read https://example.onmicrosoft.com/my_client_id/api.write
二、基于Roles的权限控制(适配客户端凭据流)
1. 在Azure AD中分配应用角色
- 在API应用的「应用角色」页面,添加两个角色:
Reader(只读)、Writer(写入) - 进入客户端应用的「企业应用」页面,找到该应用,在「用户和组」中为客户端应用分配上述角色(客户端凭据流中,角色是分配给应用而非用户)
2. 调整API代码配置
配置JWT识别角色声明,并定义授权策略:
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"), options => { // 指定Azure AD应用角色的声明类型为"roles" options.TokenValidationParameters.RoleClaimType = "roles"; }); // 定义角色授权策略 builder.Services.AddAuthorization(options => { options.AddPolicy("Reader", policy => policy.RequireRole("Reader")); options.AddPolicy("Writer", policy => policy.RequireRole("Writer")); });
3. 在控制器方法上应用角色策略
[ApiController] [Route("api/[controller]")] [Authorize] public class DataController : ControllerBase { [HttpGet] [Authorize(Policy = "Reader")] public IActionResult GetData() { return Ok("只读数据"); } [HttpPost] [Authorize(Policy = "Writer")] public IActionResult PostData([FromBody] string data) { return Ok($"已写入数据:{data}"); } }
4. 获取带角色的Token
调用token接口时,scope参数仍使用https://example.onmicrosoft.com/my_client_id/.default,客户端应用被分配的角色会自动包含在token的roles声明中。
关于Audience和Scope的区别
- Audience(受众):指定token的接收方,即你的API的唯一标识符,Azure AD会验证token的
aud声明是否与配置的Audience匹配,确保token是针对你的API颁发的。 - Scope(范围):表示客户端请求的具体权限,在token的
scp声明中体现,用于细粒度的权限划分。在客户端凭据流中,.defaultScope表示客户端被授予的所有权限都会被包含在token内。
内容的提问来源于stack exchange,提问作者Computer
相关产品推荐
相关产品推荐

