Сбор кэшированного токена через AqcuireTokenSilent завершился неудачно - PullRequest
0 голосов
/ 12 января 2020

У меня установлено условие, где, если есть кэшированный токен, он будет использовать его, иначе он будет искать переданные учетные данные или запрашивать учетные данные. Даже после однократного ввода моих учетных данных через AcquireTokenInteractive () и повторного запуска программы, она все равно запрашивает учетные данные. Если у меня есть только AcquireTokenSilent (), я получаю ошибку ссылки для переменной token, потому что ей ничего не передается. Он либо не кэширует мой токен, либо неправильно извлекает мой кэшированный токен, но я также не уверен, как устранить неполадки. Согласно MSDocs https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-acquire-cache-tokens он должен выполнять кэширование автоматически.

В настоящее время я закомментировал AcquireTokenByUsernamePassword () для устранения неполадок.

static async Task<GraphServiceClient> Auth()
        {

            string[] scopes = new string[] { "user.read" };
            string token = null;
            IPublicClientApplication app;
            app = PublicClientApplicationBuilder.Create(ConfigurationManager.AppSettings["clientId"])
                  .Build();
            AuthenticationResult result = null;
            var accounts = await app.GetAccountsAsync();
            if (accounts.Any())
            {
                result = await app.AcquireTokenSilent(scopes, accounts.FirstOrDefault())
                                  .ExecuteAsync();
            }
            else
            {
                try
                {
                    ///var securePassword = new SecureString();
                    ///foreach (char c in "dummy")        // you should fetch the password
                    ///    securePassword.AppendChar(c);  // keystroke by keystroke

                    /// result = await app.AcquireTokenByUsernamePassword(scopes,"joe@contoso.com",securePassword).ExecuteAsync();
                }
                catch (MsalException)
                {
                    ///
                }
                try
                {
                    result = await app.AcquireTokenInteractive(scopes).ExecuteAsync();
                }
                catch (MsalException)
                {
                    ///
                }
            }
            token = result.AccessToken;

            // Use the token

            GraphServiceClient graphClient = new GraphServiceClient(
                        "https://graph.microsoft.com/v1.0",
                        new DelegateAuthenticationProvider(
                            async (requestMessage) =>
                            {
                                requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", token);
                            }));
            return graphClient;
        }


1 Ответ

0 голосов
/ 13 января 2020

Да, вы правы. SDK автоматически выполнит кеширование. Я проверил это, создав консольное приложение:

    class Program
    {
        static void Main(string[] args)
        {

            string flag = "Y";

            IPublicClientApplication app = PublicClientApplicationBuilder.Create("60ef0838-f145-4f00-b7ba-a5af7f31cc3c").Build();
            string[] scopes = new string[] { "api://4a673722-5437-4663-bba7-5f49372e06ba/Group.All","openid" };

            do
            {
                List<IAccount> list = app.GetAccountsAsync().GetAwaiter().GetResult().ToList();

                Console.WriteLine("Checking cache");
                if (list.Count > 0)
                {
                    Console.WriteLine($"Find {list.Count}");
                    list.ForEach(_ =>
                    {
                        Console.WriteLine($"Acquire a new token for {_.Username}");
                        AuthenticationResult result = app.AcquireTokenSilent(scopes, _).WithForceRefresh(true).WithAuthority("https://login.microsoftonline.com/e4c9ab4e-bd27-40d5-8459-230ba2a757fb/").ExecuteAsync().Result;
                        Console.WriteLine($"New token -> {result.AccessToken}");
                    });
                }
                else
                {
                    Console.WriteLine("No cache");
                    try
                    {
                        var securePassword = new SecureString();

                        // Test AcquireTokenByUsernamePassword
                        foreach (char c in "**********") securePassword.AppendChar(c);
                        AuthenticationResult result = app.AcquireTokenByUsernamePassword(scopes, "jack@hanxia.onmicrosoft.com", securePassword).WithAuthority("https://login.microsoftonline.com/e4c9ab4e-bd27-40d5-8459-230ba2a757fb/").ExecuteAsync().GetAwaiter().GetResult();

                        // Test AcquireTokenInteractive
                        //AuthenticationResult result = app.AcquireTokenInteractive(scopes).WithAuthority("https://login.microsoftonline.com/e4c9ab4e-bd27-40d5-8459-230ba2a757fb/").ExecuteAsync().Result;
                        Console.WriteLine(result.Account.Username + " -> " + result.AccessToken);
                    }
                    catch (Exception e)
                    {
                        Console.Error.WriteLine(e.Message);
                        Console.Error.WriteLine(e.StackTrace);
                    }
                }

                Console.Write("Continue? Y/N:");
                flag = Console.ReadLine();
            } while (flag.Trim().ToUpper().Equals("Y"));

            Console.ReadLine();
        }
    }

Результат:

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...