首页 > 解决方案 > 从 winform 应用程序登录到 MigrosoftGraph

问题描述

我正在尝试从 .NET 应用程序连接到 MicrosoftGraph,但程序在读取数据时卡在一个地方。登录可能会很好,因为它会通过AccessToken返回给我,但是在检索数据时不会发生。

    Task<User> tu = graphClient.Me.Request().GetAsync();
    tu.Wait();      //it will stop me here

我在 Microsoft Graph 中创建了一个应用程序,设置了应用程序权限。但是我有什么遗漏吗???

    var tenantId = "__my tenant__";
    var appId = "__my app id__";
    var clientSecret = "__my secret__";

    //var scopes = new string[] { "https://graph.microsoft.com/.default" };
    var scopes = new string[] { "api://89__my id__1/.default" };

    // Initialize the auth provider with values from appsettings.json
    var authProvider = new DeviceCodeAuthProvider(tenantId, appId, clientSecret, scopes);

    // Request a token to sign in the user
    var accessToken = authProvider.GetAccessToken().Result;

    // Initialize Graph client
    GraphHelper.Initialize(authProvider);

    // Get signed in user
    var user = GraphHelper.GetMeAsync();        //it gets stuck inside the method
    Console.WriteLine($"Welcome {user.DisplayName}!\n");
    public class DeviceCodeAuthProvider : IAuthenticationProvider
    {
        private IConfidentialClientApplication _confidentialClientApplication;
        private string[] _scopes;
        private IAccount _userAccount;

        public DeviceCodeAuthProvider(string tenantId, string appId, string clientSecret, string[] scopes)
        {
            _scopes = scopes;
            
            _confidentialClientApplication = ConfidentialClientApplicationBuilder
                .Create(appId)
                .WithTenantId(tenantId)
                .WithClientSecret(clientSecret)
                .Build();
        }

        public async Task<string> GetAccessToken()
        {
            // If there is no saved user account, the user must sign-in
            if (_userAccount == null)
            {
                try
                {
                    var task = _confidentialClientApplication.AcquireTokenForClient(_scopes).ExecuteAsync();
                    task.Wait();
                    var result = task.Result;

                    _userAccount = result.Account;
                    return result.AccessToken;
                }
                catch (Exception exception)
                {
                    Console.WriteLine($"Error getting access token: {exception.Message}");
                    return null;
                }
            }
            else
            {
                var result = await _confidentialClientApplication
                    .AcquireTokenSilent(_scopes, _userAccount)
                    .ExecuteAsync();

                return result.AccessToken;
            }
        }

        public async Task AuthenticateRequestAsync(HttpRequestMessage requestMessage)
        {
            requestMessage.Headers.Authorization =
                new AuthenticationHeaderValue("bearer", await GetAccessToken());
        }
    }

    public class GraphHelper
    {
        private static GraphServiceClient graphClient;

        public static void Initialize(IAuthenticationProvider authProvider)
        {
            graphClient = new GraphServiceClient(authProvider);
        }

        public static User GetMeAsync()
        {
            try
            {
                // GET /me
                Task<User> tu = graphClient.Me.Request().GetAsync();
                tu.Wait();

                User u = tu.Result;
                return u;
            }
            catch (ServiceException ex)
            {
                Console.WriteLine($"Error getting signed-in user: {ex.Message}");
                return null;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error getting signed-in user: {ex.Message}");
                return null;
            }
        }
    }

标签: microsoft-graph-api

解决方案


因为您使用应用程序权限,所以支持 /me 端点

调用 /me 端点需要登录用户,因此需要委派权限。使用 /me 端点时不支持应用程序权限。https://docs.microsoft.com/en-us/graph/api/user-get?view=graph-rest-1.0&tabs=http

因此,只需包括您要访问的用户,例如

Task<User> tu = graphClient.Users["user@domain.com"].Request().GetAsync();

推荐阅读