代码:BadRequest 消息:/me 请求仅对委托身份验证流程有效

Code: BadRequest Message: /me request is only valid with delegated authentication flow

我正在尝试使用 microsoft graph onedrive api 在 onedrive 上上传文件。 我正在使用身份验证方法 客户端凭据提供程序

https://docs.microsoft.com/en-us/graph/sdks/choose-authentication-providers?tabs=CS#client-credentials-provider

喜欢:

// /.default scope, and preconfigure your permissions on the
// app registration in Azure. An administrator must grant consent
// to those permissions beforehand.
var scopes = new[] { "https://graph.microsoft.com/.default" };

// Multi-tenant apps can use "common",
// single-tenant apps must use the tenant ID from the Azure portal
var tenantId = "my-tenantid";

// Values from app registration
var clientId = "YOUR_CLIENT_ID";
var clientSecret = "YOUR_CLIENT_SECRET";

// using Azure.Identity;
var options = new TokenCredentialOptions
{
    AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
};

// https://docs.microsoft.com/dotnet/api/azure.identity.clientsecretcredential
var clientSecretCredential = new ClientSecretCredential(
    tenantId, clientId, clientSecret, options);

var graphClient = new GraphServiceClient(clientSecretCredential, scopes);

         HttpPostedFileBase file = Request.Files;[0];
                int fileSize = file.ContentLength;
                string fileName = file.FileName;
                string mimeType = file.ContentType;
                Stream fileContent = file.InputStream;


     var res = await graphClient.Me.Drive.Root.ItemWithPath(fileName).Content
                        .Request()
                        .PutAsync<DriveItem>(fileContent);

执行此代码后,会给出错误响应。

Message: /me request is only valid with delegated authentication flow.
Inner error:
    AdditionalData:
    date: 2021-12-29T05:30:08
    request-id: b51e50ea-4a62-4dc7-b8d2-b26d75268cdc
    client-request-id: b51e50ea-4a62-4dc7-b8d2-b26d75268cdc
ClientRequestId: b51e50ea-4a62-4dc7-b8d2-b26d75268cdc

客户端凭据流将代表应用程序本身生成令牌,因此在这种情况下,用户无需先登录为用户生成令牌,然后再调用api。而且由于设计原因,当你在 graph SDK 中使用 Me 时,你的 code/app 不知道 Me 是谁,所以它无法工作。你应该先知道user_id,在SDK中使用/users/{id | userPrincipalName}而不是/Me,即graphClient.Users["your_user_id"]而不是graphClient.Me

在您的场景中,有 2 种解决方案,一种方法是像您在标题中所说的那样使用委托身份验证流程,另一种方法是在调用图形 api 之前获取用户 ID,以便您可以使用 Users["id"] 但不使用 Me

=====================更新======================= ==

我还没有完成代码,但我现在找到了正确的解决方案。

首先,我们可以通过this api将文件上传到一个驱动器,如果这是一个驱动器或共享点,您可以查看屏幕截图:

https://graph.microsoft.com/v1.0/users/user_id/drive/items/root:/testupload2.txt:/content

如果是,那么下一步很简单,使用下面的代码获取访问令牌并发送 http 请求以调用 api:

var scopes = new[] { "https://graph.microsoft.com/.default" };
var tenantId = "tenant_name.onmicrosoft.com";
var clientId = "your_azuread_clientid";
var clientSecret = "corresponding_client_secret";
var clientSecretCredential = new ClientSecretCredential(
    tenantId, clientId, clientSecret);
var tokenRequestContext = new TokenRequestContext(scopes);
var token = clientSecretCredential.GetTokenAsync(tokenRequestContext).Result.Token;

我知道这很复杂,因为 api 和有 SDK 示例的 this one 不一样,但我认为如果它们相似也值得一试。