使用MSAL对接ADFS 2019时如何实现Angular应用授权访问多个Web API
ADFS 2019 + MSAL 多API访问实现方案
问题原因
ADFS 2019原生不支持在单次令牌请求中传入多个不同资源标识符对应的作用域,这是你收到MSIS9721错误的根本原因。你无需强制将所有.NET后端API合并为同一个API资源,有两种合规的实现方案:
方案1:按API维度分别请求令牌(推荐)
MSAL内置令牌缓存能力,支持增量请求不同资源的访问令牌,正常使用时不会触发重复的用户登录交互:
- 首次需要调用API1时,仅传入API1对应的作用域发起令牌请求:
const api1Request = { scopes: ['https://api1.local//openid'] } // 优先调用acquireTokenSilent静默获取令牌,失败再走弹窗/重定向流程 msalInstance.acquireTokenSilent(api1Request).then(tokenResponse => { // 使用tokenResponse.accessToken调用API1 })
- 后续需要调用API2时,仅传入API2对应的作用域发起独立的令牌请求:
const api2Request = { scopes: ['https://api2.local//openid'] } // 用户已完成身份认证,静默请求基本不会失败,无需用户二次操作 msalInstance.acquireTokenSilent(api2Request).then(tokenResponse => { // 使用tokenResponse.accessToken调用API2 })
该方案的优势:
- 不需要修改现有API的受众校验配置,适配已有服务
- 令牌权限边界清晰,每个API的访问令牌仅对应当前API的权限,安全性更高
方案2:配置统一逻辑API资源(单令牌方案)
如果希望只请求一次令牌就访问所有API,可以按你提到的思路配置统一的逻辑API组:
- 在ADFS中新建一个独立的API资源,设置其标识符为自定义的统一逻辑域名,例如
https://global-api.local - 在该统一API资源下,定义所有API需要用到的作用域,例如
api1:read、api1:write、api2:query等 - 调整所有后端API的JWT校验配置,将受众校验规则修改为接受统一API的标识符
https://global-api.local,各API在接口层面单独校验请求令牌中是否携带当前接口需要的作用域即可 - 前端只需单次请求所有需要的作用域即可:
authRequest: { scopes: ['https://global-api.local/api1:read', 'https://global-api.local/api2:query'] }
该方案的优势是只需要一次令牌请求,适合API数量多、权限模型统一的场景。
内容的提问来源于stack exchange,提问作者Yuriy Vikulov
相关产品推荐
相关产品推荐

