如何正确配置OneDrive/SharePoint文件选择器对接内部SharePoint存储?
背景
我已遵循Microsoft的所有文档,并查看了多个示例,操作步骤看似全部正确,具体执行步骤如下。
配置详情
这是企业版SharePoint,基础URL为https://{tenant}-my.sharepoint.com/_layouts/15/FilePicker.aspx,我已验证手动访问该文件选择器控件无问题。
我们通过https://{tenant}-my.sharepoint.com/.default scope刷新AAD Graph令牌来获取SharePoint令牌,该Graph令牌除应用所需其他权限外,还包含:
- User.Read
- Files.Read
- Files.Read.All
- Sites.Read.All
我的应用是Graph应用,但为确保无误,我还添加了SharePoint委托权限:
- MyFiles.Read
- AllSites.Read
令牌可正常刷新,获取的JWT包含以下关键属性:
"aud": "https://{tenant}-my.sharepoint.com", "scp": "User.Read Files.Read Files.Read.All Sites.Read.All ..."
随后我按如下代码配置文件选择器,但initializeMessageListener事件从未触发:
const click = (e: MouseEvent<HTMLButtonElement>) => { e.preventDefault(); const win = window.open("", "Picker", "width=800,height=600"); if (!win) { throw new Error("Could not open picker window"); } setupPicker(win); }; const setupPicker = async (win: Window) => { const options: IFilePickerOptions = { sdk: "8.0", entry: { sharePoint: {}, }, authentication: {}, messaging: { origin: window.location.origin, // http://localhost:5173 channelId: "27", // hard-coded for now, as in the samples }, typesAndSources: { mode: "files", }, }; const queryString = new URLSearchParams({ filePicker: JSON.stringify(options), }); const accessToken = `Bearer ${await getAccessToken()}`; // access token with properties above const url = `${baseUrl}?${queryString}`; const form = win.document.createElement("form"); form.setAttribute("action", url); form.setAttribute("method", "POST"); win.document.body.appendChild(form); const input = win.document.createElement("input"); input.setAttribute("type", "hidden"); input.setAttribute("name", "access_token"); input.setAttribute("value", accessToken); form.appendChild(input); win.addEventListener("message", initializeMessageListener); form.submit(); }; const initializeMessageListener = async (event: MessageEvent) => { console.log(event); // ideally I would setup the port here, but I never receive any messages from the window };
我从未收到来自该窗口的消息,前40秒显示空的SharePoint选择器,之后超时并弹出设置超时错误。我怀疑是消息配置存在问题,当前使用的window.location.origin为本地应用地址http://localhost:5173,无法理解为何收不到消息。
v1.0 REST API测试情况
我使用SharePoint令牌调用SharePoint API:
https://{tenant}-my.sharepoint.com/_api/web/folders
收到403 Access Denied响应。
我可以调用以下端点(/my是“我的文件”的服务器相对路径):
https://{tenant}-my.sharepoint.com/_api/web/GetFolderByServerRelativeUrl('/my')/Files
但返回空对象(与实际情况不符):
{ "d": { "results": [] } }
若直接访问该文件夹,会收到403 Access Denied响应。
v2.0 REST API测试情况
若使用原始Graph令牌,我可以调用以下URL获取用户账户的驱动器内容:
https://graph.microsoft.com/v1.0/me/drives https://graph.microsoft.com/v1.0/me/drives/{id}/root/children
内容的提问来源于stack exchange,提问作者Matt Barr

