简体   繁体   中英

Azure Graph API in .Net on desktop will not authenticate

Whenever I try to use the microsoft graph api to communicate with azure AD, no browser window will open up.

If I download a sample that uses UWP it works correctly but when I try to implement that same code in my existing application (which is not UWP) it will not work. I have also tried making a simple console application using .net 4.6.1 and again no browser window will pop up. If I put a breakpoint in the DelegateAuthenticationProvider it is never hit. If I call GetTokenForUserAsync directly then execution stays on the line with IdentityClientApp.AcquireTokenAsync indefinitely.

Is this only meant to work on UWP projects or am I doing something wrong?

using System;
using System.Linq;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using Microsoft.Azure.ActiveDirectory.GraphClient;
using Microsoft.Graph;
using Microsoft.Identity.Client;

namespace ConsoleApp1
{
    public class AuthenticationHelper
    {
        // The Client ID is used by the application to uniquely identify itself to the v2.0 authentication endpoint.
        static string clientId =     System.Configuration.ConfigurationManager.AppSettings["ida:ClientID"].ToString();
        public static string[] Scopes = { "User.Read", "Mail.Send", "Files.ReadWrite" };

        public static PublicClientApplication IdentityClientApp = new         PublicClientApplication(clientId);

        public static string TokenForUser = null;
        public static DateTimeOffset Expiration;

        private static GraphServiceClient graphClient = null;

        // Get an access token for the given context and resourceId. An attempt is first made to 
        // acquire the token silently. If that fails, then we try to acquire the token by prompting the user.
        public static GraphServiceClient GetAuthenticatedClient()
        {
            if (graphClient == null)
            {
                // Create Microsoft Graph client.
                try
                {
                    graphClient = new GraphServiceClient(
                        "https://graph.microsoft.com/v1.0",
                        new DelegateAuthenticationProvider(
                            async (requestMessage) =>
                            {
                                var token = await GetTokenForUserAsync();
                                requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", token);
                                // This header has been added to identify our sample in the Microsoft Graph service.  If extracting this code for your project please remove.
                                requestMessage.Headers.Add("SampleID", "uwp-csharp-connect-sample");

                            }));
                    return graphClient;
                }

                catch (Exception ex)
                {
                }
            }

            return graphClient;
        }


        /// <summary>
        /// Get Token for User.
        /// </summary>
        /// <returns>Token for user.</returns>
        public static async Task<string> GetTokenForUserAsync()
        {
            Microsoft.Identity.Client.AuthenticationResult authResult;
            try
            {
                authResult = await     IdentityClientApp.AcquireTokenSilentAsync(Scopes,     IdentityClientApp.Users.First());
                TokenForUser = authResult.AccessToken;
            }

            catch (Exception)
            {
                if (TokenForUser == null || Expiration <= DateTimeOffset.UtcNow.AddMinutes(5))
                {
                    authResult = await IdentityClientApp.AcquireTokenAsync(Scopes);

                    TokenForUser = authResult.AccessToken;
                    Expiration = authResult.ExpiresOn;
                }
            }

            return TokenForUser;
        }

        /// <summary>
        /// Signs the user out of the service.
        /// </summary>
        public static void SignOut()
        {
            foreach (var user in IdentityClientApp.Users)
            {
                IdentityClientApp.Remove(user);
            }
            graphClient = null;
            TokenForUser = null;

        }

    }
}

To understand the authentication with Graph API i use this sample ( that is not a UWP but a WPF)

https://github.com/Azure-Samples/active-directory-dotnet-desktop-msgraph-v2/blob/master/README.md

It's very simple and it helps me to understand the behaviour of the two different ways to get an authentication token: ( with no interaction with the user ) and ( that opens the browser for the user login ) (无需与用户交互)和 (为用户登录打开浏览器)

According to your description, I created my console application targets on .NET 4.6.1 and use MSAL for authentication and leverage Microsoft Graph .NET Client Library to communicate with Microsoft Graph API.

I reused your GetTokenForUserAsync method and executed my code snippet as follows:

static void Main(string[] args)
{
    MainAsync(args).GetAwaiter().GetResult();
}

static async Task MainAsync(string[] args)
{
    var graphClient = new GraphServiceClient(
                "https://graph.microsoft.com/v1.0",
                new DelegateAuthenticationProvider(
                    async (requestMessage) =>
                    {
                        var token = await GetTokenForUserAsync();
                        requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", token);
                    }));

    var user = await graphClient.Me.Request().GetAsync();
    Console.WriteLine(JsonConvert.SerializeObject(user));
}

Or

static void Main(string[] args)
{
    var graphClient = new GraphServiceClient(
                "https://graph.microsoft.com/v1.0",
                new DelegateAuthenticationProvider(
                    async (requestMessage) =>
                    {
                        var token = await GetTokenForUserAsync();
                        requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", token);
                    }));

    var user = graphClient.Me.Request().GetAsync().Result;
    Console.WriteLine(JsonConvert.SerializeObject(user));
    Console.WriteLine("press any key to exit...");
    Console.ReadLine();
}

TEST:

在此处输入图片说明

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM