我正在使用 Microsoft Graph 并创建了一个应用程序来读取来自特定用户的邮件。
但是,在获得访问令牌并尝试读取邮件文件夹后,我收到了 401 未经授权的答复。详细信息是:
令牌不包含权限,或权限无法理解。
这似乎是一个非常明确的信息,但不幸的是我无法找到解决方案。这是我到目前为止所做的:
为其授予应用程序权限 Mail.Read、Mail.ReadWrite ( https://docs.microsoft.com/en-us/graph/api/user-list-mailfolders?view=graph-rest-1.0 )
Run Code Online (Sandbox Code Playgroud)// client_secret retrieved from secure storage (e.g. Key Vault) string tenant_id = "xxxx.onmicrosoft.com"; ConfidentialClientApplication client = new ConfidentialClientApplication( "..", $"https://login.microsoftonline.com/{tenant_id}/", "https://dummy.example.com", // Not used, can be any valid URI new ClientCredential(".."), null, // Not used for pure client credentials new TokenCache());
string[] scopes = new string[] { "https://graph.microsoft.com/.default" };
AuthenticationResult result = client.AcquireTokenForClientAsync(scopes).Result;
string token = result.AccessToken;
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好。我确实得到了一个令牌。 …
我正在尝试更新列表项上的值(类型为超链接或图片)。执行 GET 请求时,数据返回正常,但是当我尝试创建一个项目或使用值更新它时,我最终得到以下结果:
{
"error": {
"code": "-1, Microsoft.SharePoint.Client.InvalidClientQueryException",
"message": "A value without a type name was found and no expected type is available. When the model is specified, each value in the payload must have a type which can be either specified in the payload, explicitly by the caller or implicitly inferred from the parent value.",
"innerError": {
"request-id": "d12dfb12-a068-4621-9f27-d284e4635060",
"date": "2019-05-28T08:52:51"
}
}
}
Run Code Online (Sandbox Code Playgroud)
POST/PATCH 请求转到:
https://graph.microsoft.com/v1.0/sites/<siteid>/lists/<listid>/items/
Run Code Online (Sandbox Code Playgroud)
并包含一个简单的 JSON(在 PATCH 的情况下):
{
"WebPage":
{
"Description": "Microsoft Graph",
"Url": …Run Code Online (Sandbox Code Playgroud) 这个问题是关于JSON批处理的两个问题
我尝试批处理的请求是这些请求的组合:
似乎有些租户(这是一个多租户应用程序)的限制为 4,我们的租户限制为 15,这似乎是平均值。
如果我检查提到的 20,我会收到 HTTP 400 错误请求异常。但是具有 15 到 20 个“子请求”组合的批处理请求会产生 HTTP 200 Ok 响应,其中一些 json 描述子请求的状态。那里显示429状态。
{
"id": "04",
"status": 204,
"headers": {
"Cache-Control": "private"
},
"body": null
}
Run Code Online (Sandbox Code Playgroud)
对比
{
"id": "12",
"status": 429,
"headers": {
"Retry-After": "1",
"Cache-Control": "private"
},
"body": {
"error": {
"code": "ApplicationThrottled", …Run Code Online (Sandbox Code Playgroud) 我正在向 Microsoft Graph REST api(测试版)发出请求,特别是向登录事件端点:https : //graph.microsoft.com/beta/auditLogs/signIns
我正在发出批处理请求,以 1000 个批次检索特定用户的登录信息。从 9 月 25 日左右开始,这些请求将在大约 10-50 个批次后失败,响应如下,HTTP 为 400(无效请求)错误代码:
"error": {
"code": "",
"message": "Token not found: token is either invalid or expired",
"innerError": {
"request-id": "[request-id-redacted]",
"date": "2019-09-30T22:27:36"
}
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我在等待 ~1 秒后重试请求,使用完全相同的 JWT Web 令牌,请求会成功,并且我能够完成我正在运行的作业的所有批处理请求。我在最初进行身份验证时收到的访问令牌在 1 小时后到期,但是在我收到令牌后约 1-15 分钟出现此错误(我已确认使用令牌获得的 unix 时间戳到期日期)。
我想知道这个错误的原因可能是什么,以及我如何避免它,除了硬编码特定的响应消息并重试。我也无法在 google 上找到任何匹配的错误消息。有没有人以前从 Microsoft Graph API 中看到过这个错误?
我是一个应用程序的创建者,该应用程序通过适用于 Android/iOS 的 Microsoft 图形 SDK 与 OneNote API 集成。我的几个用户报告说,新的 OneNote 笔记停止与应用程序同步(受此影响的还有数百个)。
我一直在调试这个。我可以确认 OneNote API 不会返回新页面。重现:
1) create some new notes
2) go to Graph Explorer (https://developer.microsoft.com/en-us/graph/graph-explorer/)
3) user basic query (https://graph.microsoft.com/v1.0/me/onenote/pages)
Run Code Online (Sandbox Code Playgroud)
即使几天后,也不会返回新页面。我的应用程序使用相同的端点来获取最新的页面。
如果有人能调查一下,我将不胜感激。我可以提供调试所需的所有数据。
旁注:官方 OneNote 应用程序可以正确查看笔记(在 iOS 和 Android 上)。
更新
MS Graph Explorer 开始显示 5 天前添加的注释(我们的用户报告相同)。因此,传播数据似乎有很长的延迟(官方 OneNote 应用程序几乎立即同步新页面)。收到 OneNote 团队对此的回应会很棒。
看起来类似的问题是 2 年前报道的
有没有办法克服 OneNote 客户端和 API 结果变化之间的滞后?
使用“FavorDataRecency”标头进行了测试,但仍然没有结果。
更新 2 (05.02.2020) 新笔记完全停止显示(即使在几周后测试)。有趣的是,如果我创建一个新部分,该部分会立即从 API 端点弹出(只是名称,没有注释)。
使用
`https://graph.microsoft.com/beta/users/${email}/photo/$value`
Run Code Online (Sandbox Code Playgroud)
上周一直在为我工作,但现在它抛出 400 错误 错误输出
“邮箱由内部部署或非 Exchange 服务器托管,但不受支持。”
据我所知,我们的结局没有任何改变。使用 v1.0 似乎没有任何区别。我认为用户照片存储在内部交换中,但随后在 AAD 同步。像这样至少一年以来一直运行良好。
有谁知道这几天有什么变化吗?任何记录在案的解决方案?
我想在 Microsoft Graph 中的文档授权和登录 OneDrive之后兑换访问令牌的代码
这是我用于此步骤的 API
发布https://login.microsoftonline.com/common/oauth2/v2.0/token
我已经在 Postman 上测试了 API,它工作得很好。
但是当我尝试使用 JavaScript 代码时,出现错误“仅允许‘单页应用程序’进行跨域令牌兑换”,
{
"error":"invalid_request",
"error_description":"AADSTS90023: Cross-origin token redemption is permitted only for the 'Single-Page Application' client-type.\r\nTrace ID: 57ebcf82-278c-4375-a4db-b81ab567fc00\r\nCorrelation ID: 5a80b3fa-1e0d-4265-8fbe-5e22df198bee\r\nTimestamp: 2021-04-26 10:26:36Z",
"error_codes":[
90023
],
"timestamp":"2021-04-26 10:26:36Z",
"trace_id":"57ebcf82-278c-4375-a4db-b81ab567fc00",
"correlation_id":"5a80b3fa-1e0d-4265-8fbe-5e22df198bee"
}
Run Code Online (Sandbox Code Playgroud)
因此,我尝试通过添加标头以允许来源来解决此问题,但它不起作用。以下是我的编码。我的网站托管在 firebase 上。
function RedeemToken(){
var myHeaders = new Headers();
myHeaders.append("Access-Control-Allow-Origin", "*");
myHeaders.append("Access-Control-Allow-Methods", "POST");
myHeaders.append("Access-Control-Allow-Headers", "Content-Type");
myHeaders.append("Access-Control-Max-Age", "3600");
myHeaders.append("Content-Type", "application/x-www-form-urlencoded");
var urlencoded = new URLSearchParams();
urlencoded.append("client_id", "XXXX");
urlencoded.append("redirect_uri", "https://XXXX.web.app/LinkToAuthen.html");
urlencoded.append("client_secret", "XXXX");
urlencoded.append("code", …Run Code Online (Sandbox Code Playgroud) 我们在 MS Teams 机器人上工作。每个机器人通知都包含aadObjectId在我们识别用户的请求正文中。
示例机器人请求
{"name":"composeExtension/query","type":"invoke","timestamp":"2021-04-28T06:41:18.718Z","localTimestamp":"2021-04-28T12:11:18.718+05:30","id":"f:c3c988ef-b14b-b996-b3ec-cee22dbeb5ca","channelId":"msteams","serviceUrl":"https://smba.trafficmanager.net/in/","from":{"id":"29:1FKDpJ_2YcIMpBd94h8BABBpkrv_RVSSeeJ3qh8U3djsypgk2lnJxbq_Sd4eUVFE2lHXBuUBMQ_se7QEvYzTbtQ","name":"Test Account","aadObjectId":"7812b15f-6462-44ef-a772-d9012c55bf1c"},"conversation":{"conversationType":"personal","tenantId":"4d4f9f3f-2553-430b-b86b-442be9306e29","id":"a:1W4nBEGebG_h5wTFEGuyFYXr0_vCYTvg3-lIZ9uKaPFiDZmtU5FIA2PH880C09mrtxbqEeIJ-sPQvwy0qfDhmTOPuEGRtkoT7NGS1eTBHBfjWXWFMRgOK5yzsNMlL6i0d"},"recipient":{"id":"28:97f33763-604f-89ae-40b3-719c55e66177","name":"Test Bot"},"entities":[{"locale":"en-GB","country":"GB","platform":"Web","timezone":"Asia/Calcutta","type":"clientInfo"}],"channelData":{"tenant":{"id":"4d4f9f3f-2553-430b-b86b-442be9306e29"},"source":{"name":"compose"}},"value":{"commandId":"Contacts","parameters":[{"name":"initialRun","value":"true"}],"queryOptions":{"skip":0,"count":25}},"locale":"en-GB","localTimezone":"Asia/Calcutta"}
Run Code Online (Sandbox Code Playgroud)
在初始身份验证期间,我们存储用户 ID。我们使用 OAuth2.0 和以下 Microsoft Graph API 来获取用户 ID。
https://docs.microsoft.com/en-us/graph/api/user-get?view=graph-rest-1.0&tabs=http
我们注意到id图形 api 和机器人框架中返回的业务(或工作)帐户是相同的。
但是对于个人账户就不同了
样本 ID 供参考
Work Account
From Graph API - id : 7812b15f-6462-44ef-a772-d9012c55bf1c
From Bot - aadObjectId : 7812b15f-6462-44ef-a772-d9012c55bf1c
Run Code Online (Sandbox Code Playgroud)
Personal Account
From Graph API - id : 47268d7805746036
From Bot - aadObjectId : 6542b15f-7632-a772-44ef-d9012c55bf1c
Run Code Online (Sandbox Code Playgroud)
那么如何获取个人用户的aadObjectId呢?
azure-active-directory microsoft-teams microsoft-graph-teams microsoft-graph-api
今天读了一篇关于两个PnP库“ PnP Core SDK ”和“PnP Framework”的文章。
\nPnP Core SDK 似乎是一个完全抽象 SharePoint/Teams 的 CSOM、Graph 或 REST API 的框架。
\n因此,我可以只使用 Pnp-Context,而不必再关心后台是否实际使用 Graph 或 CSOM。
\n这对我来说很有意义。
但 PnP 框架也是一个新库,它仍然提供对实际 CSOM 上下文的访问。
\n这让我很困惑,因为我现在不知道作为一名开发人员该如何行事。
我应该只使用 PnP Core SDK 吗?仅当我需要站点配置引擎时才使用 PnP 框架吗?
\n或者我可以使用 PnP 框架来执行“创建站点”、“更新列表项”等典型操作吗?
\n该文章指出了两个库之间的以下差异:
\n\n您可能想知道 PnP Framework 和 PnP Core SDK 之间有什么区别。PnP Core SDK 由 PnP 框架使用,并且以独立于 SharePoint 的 CSOM 的思维方式实现。SPO 中引入的越来越多的新功能不一定可以通过 CSOM 获得;这是 Microsoft 365 PnP 引入新 SDK 的动力,该 SDK 包含在 PnP Framework 和 …
我在我的项目中使用了 Microsoft Graph SDK 来调用图形 API,为此我需要使用 GraphServiceClient。要使用 GraphServiceClient,我必须添加一些辅助类,其中 SDKHelper 是具有 GetAuthenticatedClient() 方法的静态类。由于被测方法与静态的 SDKHelper 紧密耦合,因此我创建了一个服务类并注入了依赖项。
下面是控制器和方法,
public class MyController
{
private IMyServices _iMyServices { get; set; }
public UserController(IMyServices iMyServices)
{
_iMyServices = iMyServices;
}
public async Task<HttpResponseMessage> GetGroupMembers([FromUri]string groupID)
{
GraphServiceClient graphClient = _iMyServices.GetAuthenticatedClient();
IGroupMembersCollectionWithReferencesPage groupMembers = await _iMyServices.GetGroupMembersCollectionWithReferencePage(graphClient, groupID);
return this.Request.CreateResponse(HttpStatusCode.OK, groupMembers, "application/json");
}
}
Run Code Online (Sandbox Code Playgroud)
服务类,
public class MyServices : IMyServices
{
public GraphServiceClient GetAuthenticatedClient()
{
GraphServiceClient graphClient = new GraphServiceClient(
new DelegateAuthenticationProvider(
async (requestMessage) =>
{
string accessToken …Run Code Online (Sandbox Code Playgroud) c# ×2
azure ×1
cors ×1
csom ×1
javascript ×1
moq ×1
oauth-2.0 ×1
office365 ×1
onenote ×1
onenote-api ×1
sharepoint ×1