Microsoft Graph API UnkownError [英] Microsoft Graph API UnkownError

查看:62
本文介绍了Microsoft Graph API UnkownError的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

我使用了Fiddler来跟踪请求,并且请求OAuth令牌似乎可以正常工作.但是,当我尝试请求

对应的代码:

  IConfidentialClientApplication ConfidentialClientApplication = ConfidentialClientApplicationBuilder.Create(客户编号).WithTenantId(tenantID).WithClientSecret(clientSecret).建造();ClientCredentialProvider authProvider =新的ClientCredentialProvider(confidentialClientApplication);GraphServiceClient graphClient = new GraphServiceClient(authProvider);var children = await graphClient.Users ["{userId or UPN}"].Drive.Root.Children.要求().GetAsync(); 

  1. 如果您想使用 GraphClient.Me.Drive.Root.Children ,但又不想交互式登录,则可以选择

    对应的代码:

      IPublicClientApplication publicClientApplication = PublicClientApplicationBuilder.Create(客户编号).WithTenantId(tenantID).建造();var email ="{您的用户名}";var str ="{您的密码}";var password = new SecureString();foreach(str中的char c)密码.UsernamePasswordProvider authProvider =新的UsernamePasswordProvider(publicClientApplication,范围);GraphServiceClient graphClient = new GraphServiceClient(authProvider);var children = await graphClient.Me.Drive.Root.Children.Request().WithUsernamePassword(电子邮件,密码).GetAsync(); 

    更新2:

    不幸的是,客户端凭据流和ROPC(资源所有者密码凭据)流都不支持个人帐户.对于个人帐户,您必须使用开头提到的身份验证代码流,它要求您交互式登录.总而言之,如果没有任何其他人的互动,就不可能访问个人Onedrive.

    What am I doing wrong? I want to list the files in the root of my OneDrive. But I always get a 401 Unauthorized.

    I used Fiddler to track the requests and requesting the OAuth token seems to work fine. But when I try to request https://graph.microsoft.com/v1.0/me/drive/root/children I get Unauthorized as response with the code UnknownError

    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: I am using .NET MVC 5 and I want to access my personal onedrive without user interaction. I seem to be a bit lost with what flow I should use for this.

    解决方案

    You are calling /me/drive/root/children endpoint, so you should use a user token rather than application token.

    You are using auth code flow with:

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

    Here you need to add .WithRedirectUri(redirectUri). See sample here.

    And you should not use AcquireTokenForClient method here because it is requiring an application token with client credential flow.

    If you are trying to call Microsoft Graph in a .net core MVC, please refer to this sample.

    Acquire the access token:

    string token = await _tokenAcquisition
        .GetAccessTokenForUserAsync(GraphConstants.Scopes);
    

    If your application is .net MVC, please refer to this document.

    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;
                }
    

    UPDATE:

    There are 2 scenes that we could connect to OneDrive without any further human interaction.

    1. Use client credential flow, which allow us to call Microsoft Graph with an application token. You need to add Application Permission into your Azure AD app. You should choose Client credentials provider and use GraphClient.Users["{userId or UPN}"].Drive.Root.Children instead of GraphClient.Me.Drive.Root.Children because there is no user(/me) in this case.

    Corresponding code:

    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. If you want to use GraphClient.Me.Drive.Root.Children but don't want sign-in interactively, you could choose Username/password provider, which uses OAuth 2.0 Resource Owner Password Credentials. This scene also uses user token rather than application token.

    Please note that:

    Microsoft recommends you do not use the ROPC flow. In most scenarios, more secure alternatives are available and recommended. This flow requires a very high degree of trust in the application, and carries risks which are not present in other flows. You should only use this flow when other more secure flows can't be used.

    You need to add Delegated Permission in this case.

    Corresponding code:

    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();
    

    UPDATE 2:

    Unfortunately, both Client Credential flow and ROPC(Resource Owner Password Credentials) flow don't support personal accounts. For personal accounts, you have to use auth code flow I mentioned at the beginning and it requires you to sign-in interactively. In summary, it's impossible to access personal Onedrive without any further human interaction.

    这篇关于Microsoft Graph API UnkownError的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆