使用Duende.BFF与AAD,如何向前端传递API用户角色的最佳实践?
Duende.BFF + AAD 传递API角色到前端的最佳实践
核心原则是避免角色定义重复,同时保证角色信息的一致性与安全性,推荐以下两种最优方案:
方案一:利用AAD的应用角色分配与ID令牌扩展
依托AAD的原生能力,让用户的API角色直接出现在BFF的ID令牌中,无需额外开发:
- 步骤1:在AAD的API应用注册中维护角色(你已完成此步骤),并将这些角色分配给对应的用户/安全组(AAD门户→API应用注册→「应用角色」→「分配用户/组」)。
- 步骤2:修改BFF的应用注册,配置可选声明:进入BFF应用注册→「令牌配置」→「添加可选声明」→选择ID令牌→勾选
roles,让AAD在ID令牌中返回用户的角色信息。 - 步骤3:在Duende.BFF的配置中,确保
bff/user端点映射并返回roles声明。示例配置(Program.cs):builder.Services.AddBff().AddRemoteApis(); builder.Services.AddAuthentication(options => { options.DefaultScheme = "Cookies"; options.DefaultChallengeScheme = "OpenIdConnect"; }) .AddCookie("Cookies") .AddOpenIdConnect("OpenIdConnect", options => { options.Authority = "https://login.microsoftonline.com/your-tenant-id"; options.ClientId = "your-bff-client-id"; options.ClientSecret = "your-bff-client-secret"; options.ResponseType = "code"; options.Scope.Add("openid"); options.Scope.Add("profile"); options.Scope.Add("roles"); // 请求roles声明 options.ClaimActions.MapJsonKey("roles", "roles"); // 映射roles声明 });
前端调用/bff/user即可直接获取用户在API中的角色,全程无需重复定义角色,保证数据一致性。
方案二:通过BFF的后端API代理获取角色
如果角色是动态生成或数量过多,不适合放在ID令牌中,可利用BFF的代理能力安全获取:
- 步骤1:在API中暴露
/api/me/roles端点,该端点验证用户的API访问令牌后,返回对应的角色列表。 - 步骤2:在BFF中配置API代理,将前端请求转发到API的角色端点,示例配置:
builder.Services.AddBff() .AddRemoteApis(options => { options.AddHttpClient("api", client => { client.BaseAddress = new Uri("https://your-api-url/"); }) .AddAccessTokenHandler(); // 自动附加API访问令牌 }); // 配置代理路由 app.MapBffApiEndpoint("/bff/api/me/roles", "/api/me/roles") .RequireAuthorization(); - 步骤3:前端直接调用
/bff/api/me/roles即可获取角色,BFF会自动处理令牌的附加与验证,无需前端接触敏感令牌信息。
方案优势对比
- 对比你提到的方案1:彻底避免角色重复定义,角色仅在API应用注册中维护,消除数据不一致风险。
- 对比你提到的方案2/3:方案一利用ID令牌原生传递角色,无额外API请求开销;方案二依托BFF的成熟代理能力,比手动创建
/bff/roles端点更简洁、更安全,符合BFF架构的安全设计原则。
内容的提问来源于stack exchange,提问作者pr177
相关产品推荐
相关产品推荐

