Azure AD v1.0端点下SPA与Web API访问控制方案咨询
Azure AD v1.0 场景下Web API承担访问控制的实现建议
刚好之前在项目里处理过类似的Azure AD v1.0 + SPA + Web API的架构,给你分享几个经过实践验证的实现思路,帮你把访问控制逻辑完全迁移到Web API端:
1. 先筑牢基础:确保Web API能正确验证Access Token
这是所有访问控制的前提,必须保证SPA发送过来的access_token是合法、有效的,且确实是针对你的Web API颁发的:
- 在Azure AD门户里给Web API做应用注册,设置好应用ID URI(作为token的受众
aud),并确保SPA的应用注册已经获得了该Web API的访问权限。 - 代码层面,以ASP.NET Core为例,用
Microsoft.AspNetCore.Authentication.JwtBearer中间件配置验证逻辑:services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.Authority = "https://login.microsoftonline.com/你的租户ID"; options.Audience = "https://你的WebAPI应用IDURI"; // 必须和Azure AD里配置的一致 options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ClockSkew = TimeSpan.FromMinutes(5) // 处理网络延迟导致的时间偏差 }; }); - 验证通过后,Web API就能通过
User对象获取token里的所有声明信息了。
2. 用Azure AD内置角色(RBAC)实现粗粒度访问控制
如果你的访问控制是基于用户角色(比如管理员、普通用户),直接用Azure AD的应用角色功能最省心:
- 在Web API的应用注册里,添加应用角色(比如
Admin、RegularUser),然后在Azure AD的企业应用中,把用户/安全组分配到对应的角色。 - 当用户登录后,access_token里会包含
roles声明,Web API可以直接用内置的授权特性控制访问:// 控制器级别的角色控制 [Authorize(Roles = "Admin")] [ApiController] [Route("api/[controller]")] public class AdminController : ControllerBase { // 只有Admin角色的用户能访问这里的接口 } // 方法级别的角色控制 [HttpGet("sensitive-data")] [Authorize(Roles = "Admin,Editor")] public IActionResult GetSensitiveData() { // 逻辑代码 }
3. 用API权限(Scopes)实现细粒度权限控制
如果需要更精细的控制(比如某个接口只能被允许读取订单的用户访问),就用API的scopes:
- 在Web API的应用注册里添加API权限(Scopes),比如
Orders.Read、Orders.Write、Customers.Manage。 - 确保SPA在请求access_token时,把需要的scopes作为请求参数(比如
https://你的WebAPI应用IDURI/Orders.Read),这样access_token里会包含scp声明,列出用户拥有的权限。 - 在Web API里自定义授权策略来检查这些scopes:
然后在接口上应用策略:services.AddAuthorization(options => { options.AddPolicy("CanReadOrders", policy => policy.RequireClaim("scp", "Orders.Read")); options.AddPolicy("CanWriteOrders", policy => policy.RequireClaim("scp", "Orders.Write")); });[HttpGet("orders")] [Authorize(Policy = "CanReadOrders")] public IActionResult GetOrders() { // 只有拥有Orders.Read权限的用户能访问 }
4. 自定义声明实现业务专属访问控制
如果你的访问控制依赖业务相关的属性(比如用户所属部门、项目ID),可以通过自定义声明来实现:
- 在Azure AD里,你可以通过扩展属性或者使用Azure AD Graph API(v1.0)给用户添加自定义属性,然后配置token发行时把这些属性作为声明包含进去。
- 也可以在Web API验证token后,调用Microsoft Graph API获取用户的额外业务信息,不过这种方式会增加接口延迟,建议优先把必要的信息放到token声明里。
- 比如要检查用户所属部门,可以在token里添加
department声明,然后在Web API里手动判断:[HttpGet("department-data")] [Authorize] public IActionResult GetDepartmentData() { var userDepartment = User.FindFirstValue("department"); if (userDepartment != "Sales") { return Forbid(); // 拒绝非销售部门的用户访问 } // 业务逻辑 }
5. 安全最佳实践
- 绝对不要信任SPA传来的任何额外信息:比如用户ID、角色、权限这些,所有访问控制决策必须基于Web API自己验证后的access_token声明。
- 启用token的严格验证:包括发行人、受众、有效期,中间件默认会处理,但要确保配置正确。
- 敏感接口强制MFA:可以在Azure AD里配置条件访问策略,要求访问Web API的用户必须完成多因素认证,此时token里会包含
amr声明(值为mfa),Web API可以检查这个声明来强制MFA。 - 定期轮换密钥:Azure AD会自动管理密钥,但如果是自定义签名的话,要定期轮换密钥保证安全。
内容的提问来源于stack exchange,提问作者Maqsood Ali Bhatti - bElaie.
相关产品推荐
相关产品推荐

