"Unsupported app only token" 查询 OneDrive for Business 时

"Unsupported app only token" when query OneDrive for Business

使用 App-Only 访问令牌,访问令牌 (jwt) 如下所示

...
"aud": "https://{tenant}-my.sharepoint.com/",
...
"roles": [
    "User.Read.All",
    "TermStore.Read.All",
    "Sites.Read.All"
  ],
...

然后使用 curl

curl -H "Content-Type: application/x-www-form-urlencoded" -H "Authorization:Bearer {access_token}" 'https://{tenant}-my.sharepoint.com/_api/v2.0/drives/{upn}/root'

Returns

"Unsupported app only token."

如果使用用户登录访问令牌,它可以正常工作。

此外,我不能使用“https://graph.microsoft.com/v1.0/drives/{upn}/root/”,因为 API 是 "https://{tenant}-my.sharepoint.com/_api/v2.0/".

的子集

App-Only 访问令牌应该如何读取 OneDrive?

此外,"application permission" 和 "delegate permission" 的 Azure 网络应用程序中的 "required permissions" 与 "Office 365 SharePoint Online" 不同,因为没有 "File Read" "application permission"。此权限重要吗?

"OneDrive Business" API 需要一个 appidacr 值为 2 的标记。

0 = Public 客户
1 = 客户端由其 id 和 secret 标识
2 = 客户端由其证书标识

评论中提到的 1 的值表明使用了 id/secret 而不是使用证书。要为您的应用程序设置证书,请遵循 these instructions,然后您可以使用如下代码获取令牌:

var context = new AuthenticationContext(authEndpoint); 
X509Certificate2 cert = new X509Certificate2(clientCertificatePfxPath, clientCertificatePfxPassword, X509KeyStorageFlags.MachineKeySet);
ClientAssertionCertificate cac = new ClientAssertionCertificate(ClientId, cert);
var token = context.AcquireToken(audience, cac);

更新 1
以下包括一个很好的示例,说明如何在不使用 ADAL 的情况下获取令牌:
http://www.cloudidentity.com/blog/2015/02/06/requesting-an-aad-token-with-a-certificate-without-adal/

引自此来源:

POST https://login.windows.net/contoso.onmicrosoft.com/oauth2/token
HTTP/1.1 Content-Type: application/x-www-form-urlencoded
client-request-id: a2ef0cd8-60e5-4620-ac66-6f2a344e075b
return-client-request-id: true Host: login.windows.net
Content-Length: 986
Expect: 100-continue
Connection: Keep-Alive

resource=https%3A%2F%2Fcontoso.onmicrosoft.com%2FTodoListService&client_id=82692da5-a86f-45c9-9d53-2f88d51b478b&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer &client_assertion=eyJhbGciOi[…a lot of stuff…]-j5UBo1A&grant_type=client_credentials

The main things to notice here:
1) it’s a POST to the token endpoint
2) it is a client_credentials grant, as expected
3) you need to specify as client_assertion_type the magic value urn:ietf:params:oauth:client-assertion-type:jwt-bearer

The other thing of interest is in the client_assertion itself, which is the artifact in which the certificate actually comes into play: it’s an assertion you need to create and sign with the certificate you registered as credential for your application. ADAL does this for you, ut if you want to work directly at the protocol level you’ll have to do it yourself.

按照 link 了解有关如何生成用于断言的 JWT 的详细信息。

更新 2
James 找到了更好的资源 - 查看 this link 以获取有关如何使用 Azure AD 手动执行证书身份验证的分步说明。