如何在Entra中为不同用户分配Web API的特定MSAL权限范围?
在Entra(原Azure AD)中,默认的委托权限(Scopes)是应用级授权——只要UI应用被授予了Books.Write和Authors.Write范围,用户同意后就能拿到所有请求的范围,无法直接按用户级别过滤。要实现你需要的用户级权限分配,有两种可行方案:
方案一:用应用角色(App Roles)替代权限范围
这是Entra官方推荐的用户级权限分配方式,直接通过角色绑定实现细粒度控制:
将权限范围转为应用角色
在Web API的Entra注册页面,进入「应用角色」选项,添加两个角色:- 角色名称:
Books.Write,显示名称:允许写入书籍,描述:拥有写入书籍数据的权限,类型选择「用户/组」 - 角色名称:
Authors.Write,显示名称:允许写入作者,描述:拥有写入作者数据的权限,类型选择「用户/组」
- 角色名称:
给用户分配对应角色
在Entra的「企业应用」中找到你的Web API应用,进入「用户和组」:- 添加用户Jane,分配
Books.Write角色 - 添加用户John,分配
Authors.Write角色 - 添加用户Bill,同时分配两个角色
- 添加用户Jane,分配
调整UI应用的请求范围
UI应用在认证时,请求API的默认用户范围(比如api://<你的API客户端ID>/access_as_user),无需再单独请求Books.Write和Authors.Write。API端验证权限
用户获取的令牌中会包含roles声明,API只需检查该声明里的角色,即可判断用户是否拥有对应权限。比如:// 示例:ASP.NET Core中验证角色 [Authorize(Roles = "Books.Write")] public IActionResult CreateBook() { // 处理书籍写入逻辑 }
方案二:自定义属性+API端过滤(保留原权限范围)
如果必须保留原有的Books.Write和Authors.Write权限范围,可以通过以下方式实现:
给用户添加自定义安全属性
在Entra中给每个用户配置自定义属性,比如添加AllowedScopes属性:- Jane的
AllowedScopes值:Books.Write - John的
AllowedScopes值:Authors.Write - Bill的
AllowedScopes值:Books.Write,Authors.Write
- Jane的
API端过滤权限
UI应用仍请求两个权限范围,API拿到令牌后:- 通过令牌中的
oid(用户对象ID)查询Entra获取该用户的AllowedScopes属性 - 对比令牌中的
scp声明(包含UI请求的所有范围),只保留用户被允许的范围 - 根据过滤后的范围进行权限校验
- 通过令牌中的
注意:这种方案需要API额外调用Entra Graph API查询用户属性,会增加请求开销,不如方案一高效。
关键说明
Entra的委托权限(Scopes)设计目的是授予应用访问API的权限,而非直接控制单个用户的权限。因此用户级的细粒度控制,官方更推荐用应用角色来实现,既能利用Entra的原生权限管理能力,又能简化API端的验证逻辑。
内容的提问来源于stack exchange,提问作者Kyle

