首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场

Microsoft
EN

Stack Overflow用户
提问于 2020-12-16 16:41:25
回答 1查看 398关注 0票数 0

我做错了什么?我想在我的OneDrive根目录中列出这些文件。但我总是得到一个401未经授权的

我使用Fiddler跟踪请求,请求OAuth令牌似乎很好。但是,当我试图请求https://graph.microsoft.com/v1.0/me/drive/root/children时,我会得到未经授权的代码UnknownError的响应。

代码语言:javascript
运行
复制
private static GraphServiceClient GetAuthenticatedGraphClient()
    {
        List<string> scopes = new List<string>
        {
            "https://graph.microsoft.com/.default",
        };


        var cca = ConfidentialClientApplicationBuilder.Create(CLIENT_ID)
                                                .WithAuthority(AadAuthorityAudience.PersonalMicrosoftAccount)
                                                .WithClientSecret(SECRET)
                                                .Build();

        GraphServiceClient graphServiceClient =
            new GraphServiceClient(new DelegateAuthenticationProvider(async (requestMessage) =>
                {
                    // Retrieve an access token for Microsoft Graph (gets a fresh token if needed).
                    var authResult = await cca.AcquireTokenForClient(scopes).ExecuteAsync();

                    // Add the access token in the Authorization header of the API
                    requestMessage.Headers.Authorization =
                        new AuthenticationHeaderValue("Bearer", authResult.AccessToken);
                })
            );

        return graphServiceClient;
    }

var drive = GraphClient.Me.Drive.Root.Children.
Request().
GetAsync();

FYI:我使用的是.NET MVC 5,我想在没有用户交互的情况下访问我的个人 onedrive。我似乎有点不知所措,我应该用什么流程来处理这个问题。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-12-17 02:35:41

您正在调用/me/drive/root/children端点,因此应该使用用户令牌而不是应用程序令牌。

您使用的auth码流与:

代码语言:javascript
运行
复制
var cca = ConfidentialClientApplicationBuilder.Create(CLIENT_ID)
              .WithAuthority(AadAuthorityAudience.PersonalMicrosoftAccount)
              .WithClientSecret(SECRET)
              .Build();

在这里您需要添加.WithRedirectUri(redirectUri)。参见示例这里

这里不应该使用AcquireTokenForClient方法,因为它需要一个带有客户凭证流的应用程序令牌。

如果您试图在.net核心MVC中调用Microsoft,请参阅此示例

获取访问令牌:

代码语言:javascript
运行
复制
string token = await _tokenAcquisition
    .GetAccessTokenForUserAsync(GraphConstants.Scopes);

如果您的应用程序是.net MVC,请参阅此文档

代码语言:javascript
运行
复制
var idClient = ConfidentialClientApplicationBuilder.Create(appId)
                .WithRedirectUri(redirectUri)
                .WithClientSecret(appSecret)
                .Build();

            string message;
            string debug;

            try
            {
                string[] scopes = graphScopes.Split(' ');

                var result = await idClient.AcquireTokenByAuthorizationCode(
                    scopes, notification.Code).ExecuteAsync();

                message = "Access token retrieved.";
                debug = result.AccessToken;
            }

更新:

有两个场景,我们可以连接到OneDrive,而不需要任何进一步的人类互动。

  1. 使用客户凭证流,它允许我们使用应用程序令牌调用Microsoft。您需要将应用程序权限添加到您的Azure应用程序中。您应该选择客户端凭证提供程序,使用GraphClient.Users["{userId or UPN}"].Drive.Root.Children而不是GraphClient.Me.Drive.Root.Children,因为在本例中没有用户(/me)。

相应代码:

代码语言:javascript
运行
复制
IConfidentialClientApplication confidentialClientApplication = ConfidentialClientApplicationBuilder
    .Create(clientId)
    .WithTenantId(tenantID)
    .WithClientSecret(clientSecret)
    .Build();

ClientCredentialProvider authProvider = new ClientCredentialProvider(confidentialClientApplication);

GraphServiceClient graphClient = new GraphServiceClient(authProvider);

var children = await graphClient.Users["{userId or UPN}"].Drive.Root.Children
    .Request()
    .GetAsync();
  1. 如果您想使用GraphClient.Me.Drive.Root.Children,但不希望交互登录,则可以选择使用OAuth 2.0资源所有者密码凭据用户名/密码提供程序。这个场景还使用用户令牌而不是应用程序令牌。

请注意:

Microsoft建议您不要使用ROPC流。在大多数情况下,更安全的替代方案是可用和推荐的。这个流程需要对应用程序有很高程度的信任,并且具有在其他流中不存在的风险。只有当其他更安全的流不能使用时,才应该使用此流。

在本例中,您需要添加委托权限

相应代码:

代码语言:javascript
运行
复制
IPublicClientApplication publicClientApplication = PublicClientApplicationBuilder
            .Create(clientId)
            .WithTenantId(tenantID)
            .Build();

var email = "{your username}";
var str = "{your password}";
var password = new SecureString();
foreach (char c in str) password.AppendChar(c);

UsernamePasswordProvider authProvider = new UsernamePasswordProvider(publicClientApplication, scopes);

GraphServiceClient graphClient = new GraphServiceClient(authProvider);

var children= await graphClient.Me.Drive.Root.Children.Request()
                .WithUsernamePassword(email, password)
                .GetAsync();

更新2:

不幸的是,客户凭证流和ROPC(资源所有者密码凭据)流都不支持个人帐户。对于个人帐户,您必须使用我在开头提到的auth代码流,它要求您以交互的方式登录。总之,如果没有任何进一步的人类交互,就不可能访问个人Onedrive。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65327473

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档