问题描述
我正在尝试使用 Typescript 在 React 中开发一个单词插件,它允许我访问 dynamics 365 Web Api。我实际发现的最佳示例是在示例 excel 添加中,它使用 MSAL 2.0 访问图形 api https://github.com/OfficeDev/PnP-OfficeAddins/tree/master/Samples/auth/Office-Add-in-Microsoft-Graph-React。如果我可以在修改示例代码后成功获取到我的 Dynamics 365 api 的请求,我会将代码移植到我的 Word 插件中。
但是,我在尝试访问 https://saltrial.crm.dynamics.com/api/data/v9.1/
时不断收到 401 错误
当我简单地将其粘贴到浏览器中时,我得到了回复,但在添加中我得到 401 未经授权。当我将从 add in 收到的令牌粘贴到带有 Bearer + token 标头的邮递员时,我也得到了 401 未授权。但是当我选择时,我已经获得了一个成功的访问令牌
我将向您展示我在 Azure AD 中的设置......我有一个客户端机密设置,但我没有在我的插件代码中使用它。
清单 { "id": "35c3a758-0edb-45f6-a97d-9c7180decd73","acceptMappedClaims": null,"accesstokenAcceptedVersion": 2,“插件”:[], “allowPublicclient”:真, "appId": "4f7xxxxxxxxxxxxxxxxxxxxxxxx310bf0",“应用角色”:[], “oauth2AllowUrlPathMatching”:假, "createdDateTime": "2021-01-24T07:09:12Z",“disabledByMicrosoftStatus”:空, "groupMembershipClaims": null,“标识符Uris”:[ "api://localhost:3000/4fxxxxxxxxxxxxxxxxxxxxxxxxxx" ],“信息网址”:{ “服务条款”:空, “支持”:空, “隐私”:空, “营销”:空 },"keyCredentials": [],"kNownClientApplications": [],“logoUrl”:空, “logoutUrl”:空, "name": "TrySSO",“oauth2AllowIdTokenImplicitFlow”:真, “oauth2AllowImplicitFlow”:真, “oauth2Permissions”:[ { "adminConsentDescription": "启用 Office 以与当前用户相同的权限调用加载项的 Web API。","adminConsentdisplayName": "Office 可以充当用户","id": "5b3a4e4a-e55e-45ba-820b-ea16efbe3d5f",“已启用”:真, “朗”:空, "origin": "应用程序","type": "用户","userConsentDescription": "启用 Office 以您拥有的相同权限调用加载项的 Web API。","userConsentdisplayName": "Office 可以充当你",“值”:“access_as_user” } ],“oauth2RequirePostResponse”:假, “可选声明”:空, “组织限制”:[], “家长控制设置”:{ "countriesBlockedForMinors": [],"legalAgeGroupRule": "允许" },“密码凭据”:[ { “customKeyIdentifier”:空, "endDate": "2299-12-31T05:00:00Z","keyId": "570axxxxxxxxxxxxxxxxxxxxxxxxxxxxbcd1","startDate": "2021-01-28T04:11:05.086Z",“值”:空, "createdOn": "2021-01-28T04:11:06.027737Z","提示": "mm-","displayName": "wordaddinsecret" } ],“预授权应用程序”:[ { "appId": "ea5a67f6-b6f3-4338-b240-c655ddc3cc8e",“权限ID”:[ “5b3a4e4a-e55e-45ba-820b-ea16efbe3d5f” ] },{ "appId": "d3590ed6-52b3-4102-aeff-aad2292ab01c",{ "appId": "57fb890c-0dab-4253-a5e0-7188c88b2bb4",{ "appId": "bc59ab01-8403-45c6-8796-ac3ef710b3e3",“权限ID”:[ “5b3a4e4a-e55e-45ba-820b-ea16efbe3d5f” ] } ],"publisherDomain": "salnewtrial.onmicrosoft.com","replyUrlsWithType": [ { "url": "https://localhost:3000/login/login.html",“类型”:“温泉” },{ "url": "https://login.microsoftonline.com/common/oauth2/nativeclient",“类型”:“已安装的客户端” },{ "url": "https://localhost:3000/login.html",“类型”:“网页” } ],“必需的资源访问”:[ { "resourceAppId": "00000007-0000-0000-c000-000000000000",“资源访问”:[ { "id": "78ce3f0f-a1ce-49c2-8cde-64b5c0896db4",“类型”:“范围” } ] },{ "resourceAppId": "00000003-0000-0000-c000-000000000000",“资源访问”:[ { "id": "14dad69e-099b-42c9-810b-d002981feec1",“类型”:“范围” },{ "id": "7427e0e9-2fba-42fe-b0c0-848c9e6a8182",{ "id": "37f7f235-527c-4136-accd-4a02d197296e",{ "id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d",“类型”:“范围” } ] } ],“samlMetadataUrl”:空, “signInUrl”:空, "signInAudience": "AzureADMyOrg",“标签”:[], “tokenEncryptionKeyId”:空 }
在我的login.ts里面的excel添加
(() => {
// The initialize function must be run each time a new page is loaded
Office.initialize = () => {
const msalInstance = new PublicclientApplication({
auth: {
clientId: "4f7f40ec-xxxxxxxxx-5d6b18310bf0",authority: "https://login.microsoftonline.com/cd77a053-xxxxxxxxxx3402c0fd62",*This is tenant id
redirectUri: "https://localhost:3000/login/login.html",// Must be registered as "spa" type
},cache: {
cacheLocation: "localStorage",// needed to avoid "login required" error
storeAuthStateInCookie: true,// recommended to avoid certain IE/Edge issues
},});
// handleRedirectPromise should be invoked on every page load
msalInstance
.handleRedirectPromise()
.then((response) => {
// If response is non-null,it means page is returning from AAD with a successful response
if (response) {
Office.context.ui.messageParent(
JSON.stringify({ status: "success",result: response.accesstoken })
);
} else {
// Otherwise,invoke login
msalInstance.loginRedirect({
scopes: [
"user.read","files.read.all","https://saltrial.crm.dynamics.com//user_impersonation",],});
}
})
.catch((error) => {
const errorData: string = `errorMessage: ${error.errorCode}
message: ${error.errorMessage}
errorCode: ${error.stack}`;
Office.context.ui.messageParent(
JSON.stringify({ status: "failure",result: errorData })
);
});
};
})();
这是我在 Add in 中的 API 调用
import axios from 'axios';
export const getGraphData = async (url: string,accesstoken: string) => {
const response = await axios({
url: url,method: 'get',headers: {'Authorization': `Bearer ${accesstoken}`,'OData-MaxVersion': '4.0','OData-Version': '4.0',"Accept": "application/json","Content-Type": "application/json; charset=utf-8",}
});
return response;
};
调用我的 api 函数并传递范围和动态 url 的代码。我控制台记录访问令牌并将其放入带有标题承载令牌的邮递员,我得到 401。此外,加载项在任务窗格中显示 401 未经授权......忽略任何引用图形 API 的函数命名,我是点击动态 365 api 并希望我没有收到 401 错误。谢谢。
getFileNames = async () => {
this.setState({ fileFetch: "fetchInProcess" });
getGraphData(
// Get the `name` property of the first 3 Excel workbooks in the user's OneDrive.
"https://saltrial.crm.dynamics.com/api/data/v9.1/WhoAmI",this.accesstoken
)
.then(async (response) => {
await writeFileNamesToWorksheet(response,this.displayError);
this.setState({ fileFetch: "fetched",headerMessage: "Success" });
})
.catch((requestError) => {
// If this runs,then the `then` method did not run,so this error must be
// from the Axios request in getGraphData,not the Office.js in
// writeFileNamesToWorksheet
console.log("Access Token >>>>>>>>>>>>>>>>> ",this.accesstoken);
this.displayError(requestError);
});
};
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)