Outlook插件应用无法获取SSO Token问题求助
问题背景
按照微软Office SSO开发文档实现后端获取SSO Token,具体实现如下:
前端代码(获取Access Token并传递给后端)
OfficeRuntime.auth .getAccessToken({ allowConsentPrompt: true, allowSignInPrompt: true, forMSGraphAccess: true }) .then((token) => { console.log(token); axios .get(process.env.REACT_APP_FUNC_ENDPOINT + URLS.GET_GRAPH_DATA, { headers: { Authorization: "Bearer " + token }, }) .then((data) => { console.log(data); event.completed(); }); });
后端代码(通过On-Behalf-Of流程兑换Graph Token)
export async function getAccessToken(authorization: string): Promise<any> { if (!authorization) { let error = new Error("No Authorization header was found."); return Promise.reject(error); } else { const scopeName: string = process.env.SCOPE || "User.Read"; const [, /* schema */ assertion] = authorization.split(" "); const tokenScopes = (jwt.decode(assertion) as jwt.JwtPayload).scp.split( " " ); const accessAsUserScope = tokenScopes.find( (scope) => scope === "access_as_user" ); if (!accessAsUserScope) { throw new Error("Missing access_as_user"); } const formParams = { client_id: process.env.CLIENT_ID, client_secret: process.env.CLIENT_SECRET, grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer", assertion: assertion, requested_token_use: "on_behalf_of", scope: [scopeName].join(" "), }; const stsDomain: string = "https://login.microsoftonline.com"; const tenant: string = "common"; const tokenURLSegment: string = "oauth2/v2.0/token"; const encodedForm = form(formParams); let tokenResponse; try { tokenResponse = await axios.post( `${stsDomain}/${tenant}/${tokenURLSegment}`, encodedForm, { headers: { Accept: "application/json", "Content-Type": "application/x-www-form-urlencoded", }, } ); } catch (error) { console.log(error); } return tokenResponse.data; } }
遇到的问题
- 触发错误:
'AADSTS65001: The user or administrator has not consented to use the application with ID '64f01276-0XXX' named 'ssoaddins'. Send an interactive authorization request for this user and resource.\r\nTrace ID: 9a6a62f0-e698-48f3-ac77-ca18c0bbbd00\r\nCorrelation ID: 58843565-b171-4165-ab24-face78a43dfb\r\nTimestamp: 2023-03-15 01:23:42Z'
前端已设置
allowConsentPrompt: true,但未弹出用户授权界面,且已在Azure中配置无需管理员审批的委托权限。
- 调整代码后获取的Graph Token无效。
问题解答
一、allowConsentPrompt: true未弹出授权界面且触发AADSTS65001错误的场景
以下几种情况会导致该问题:
- 前后端权限范围不匹配:前端调用
getAccessToken时仅设置forMSGraphAccess: true,未明确指定scopes参数,默认仅请求access_as_user权限,未包含后端需要的User.Read等Graph权限。此时后端用On-Behalf-Of流程请求未被前端预授权的权限,无法触发前端授权弹窗。 - 租户权限策略限制:即使Azure配置了无需管理员审批的权限,若租户管理员设置「禁止用户自行同意应用权限」策略,会直接拦截授权弹窗,导致无法完成同意流程。
- Office客户端环境限制:
- 桌面版Office中,系统弹窗拦截器可能阻止授权窗口弹出;
- 浏览器版Office运行在iframe中,部分浏览器的跨域安全策略会限制弹窗显示。
- 应用注册权限未生效:虽然配置了权限,但权限处于「已请求」状态而非「已授予」——用户从未手动同意过该应用权限,或管理员未批量授予,即使权限无需审批,也需要触发一次授权流程才能生效。
- 前端流程提前终止:代码中
event.completed()在授权或后端请求完成前调用,导致Office客户端提前结束任务,终止授权弹窗流程。
二、Graph Token无效的解决方法
按以下步骤排查修复:
验证Token核心字段
用JWT解码工具解析Token,检查:aud字段是否为https://graph.microsoft.com(有效Graph Token的受众必须是该地址);scp字段是否包含所需的Graph权限(如User.Read);exp字段是否未过期。
检查后端On-Behalf-Of参数
确保参数配置正确:client_id和client_secret与Azure应用注册信息完全一致;scope参数严格匹配需要的Graph权限(多个权限用空格分隔);grant_type和requested_token_use分别为urn:ietf:params:oauth:grant-type:jwt-bearer和on_behalf_of;- STS请求地址
https://login.microsoftonline.com/common/oauth2/v2.0/token正确(单租户应用需替换common为租户ID/域名)。
完善后端错误捕获
修改后端catch块,返回详细错误信息,便于定位问题:catch (error) { const errMsg = error.response?.data || error.message; console.error("Token兑换失败:", errMsg); return Promise.reject(errMsg); }确保前端传递的Token有效
解码前端获取的Access Token,确认:- 包含
access_as_user权限; iss(签发者)和aud(受众)符合Office SSO要求(iss应为https://login.microsoftonline.com/{tenantId}/v2.0,aud应为应用注册的Client ID)。
- 包含
调整前端权限请求
在getAccessToken中明确指定后端需要的Graph权限,确保前端预授权:OfficeRuntime.auth .getAccessToken({ allowConsentPrompt: true, allowSignInPrompt: true, forMSGraphAccess: true, scopes: ["User.Read"] // 匹配后端的scope配置 }) .then((token) => { // 后续逻辑 });
内容的提问来源于stack exchange,提问作者infodev
相关产品推荐
相关产品推荐

