采用OpenID Connect实现SSO的.NET应用如何通过前端JS查询Microsoft Graph?
解决方法
基于你现有的技术栈和需求,以下是两种可直接落地的方案,都不需要新增Graph API透传代理:
方案1:复用现有后端OIDC授权流(改造量极小)
你用的Microsoft.Owin.Security.OpenIdConnect原生支持在授权阶段同时申请Graph API令牌,只需要调整少量配置即可:
- 修改
Startup.Auth.cs中的OpenIdConnectAuthenticationOptions配置:- 把
ResponseType设为OpenIdConnectResponseType.CodeIdToken - 在
Scope属性中追加需要的Graph权限和离线访问权限,示例:Scope = "openid profile email offline_access User.Read",offline_access是获取刷新令牌的必填项 - 开启
SaveTokens = true,OWIN会自动将ID令牌、访问令牌、刷新令牌加密存储到用户的认证Cookie中
- 把
- 后端新增一个最小逻辑的受保护接口,仅返回当前登录用户的Graph访问令牌,同时返回令牌过期时间戳,这个接口仅做令牌下发,不属于你提到的业务代理接口范畴
- 前端拿到令牌后,直接在Graph请求头带上
Authorization: Bearer {access_token}即可调用,令牌到期前1~2分钟调用接口用刷新令牌换发新的访问令牌即可
方案2:前端用MSAL.js静默拿令牌(后端零改造)
如果不想修改现有后端逻辑,直接用前端MSAL.js库利用已有身份提供商会话静默获取令牌即可:
- 前端引入MSAL.js v2版本,初始化配置和你后端用的客户端ID、租户ID保持一致
- 页面加载时调用
acquireTokenSilent方法传入Graph权限scope,因为用户已经通过SSO登录过身份提供商,该请求不会弹出登录窗,会直接返回有效访问令牌 - MSAL.js会自动处理令牌过期、静默刷新逻辑,不需要你自行维护刷新逻辑,拿到令牌后直接调用Graph API即可
- 该方案完全独立于你现有的后端SSO逻辑,不会产生登录状态冲突,也不需要后端做任何改造
注意事项
- 不要将访问令牌存储在
localStorage/sessionStorage中,避免XSS攻击窃取,优先存放在前端内存变量中,页面刷新时重新静默获取即可 - 如果采用方案1,令牌下发接口必须加CSRF防护,仅允许当前登录用户获取自己的令牌
- 申请Graph权限时遵循最小权限原则,不要申请超出业务需要的高权限
内容的提问来源于stack exchange,提问作者Hidden
相关产品推荐
相关产品推荐

