Поток аутентификации Azure в настольном приложении (WinForms C#)

Я отправлял почту через SMTP (и читал через IMAP) через Azure, используя OAuth для настольного приложения (C# WinForms .NET Framework 4.8). Учетная запись имеет MFA, но это не учетная запись Windows. Я прочитал несколько статей, тем и примеров, но никто не подал заявку, и кажется невозможным завершить поток аутентификации пользователя, чтобы получить токен для учетной записи, если приложение не является веб-приложением.

Следующий код работает, но я не могу получить токен доступа для определенной учетной записи:

public static readonly string[] SCOPES = new string[] { "https://outlook.office.com/IMAP.AccessAsUser.All", "https://outlook.office.com/SMTP.Send", "https://outlook.office.com/User.Read" };
public static readonly string[] SCOPES_IMAP = { "https://outlook.office.com/IMAP.AccessAsUser.All" };


string oAuthTenantId = this.txtOAuthTenantId.Text;
string oAuthClientId = this.txtOAuthClientId.Text;
string oAuthSecret = this.txtOAuthSecret.Text;

IConfidentialClientApplication oAuthApp = ConfidentialClientApplicationBuilder.Create(oAuthClientId)
    .WithClientSecret(oAuthSecret)
    .WithAuthority(new Uri($"https://login.microsoftonline.com/{oAuthTenantId}"))
    .WithRedirectUri("https://localhost") 
    .Build();

var authUrl = oAuthApp.GetAuthorizationRequestUrl(SCOPES).ExecuteAsync().Result;
var accessToken = oAuthApp.AcquireTokenForClient(SCOPE_DEFAULT).ExecuteAsync().Result;

Я тоже использую веб-приложение, и там это «легко», я использую authUrl, чтобы перенаправить пользователя в поток аутентификации MS, но в настольном приложении я не знаю, как это сделать.

Не могли бы вы подтвердить, требуется ли вам генерировать токен с использованием потока аутентификации Azure в настольном приложении Winforms C# с MFA?

Sridevi 28.08.2024 12:16

Да, в этом вся суть!

Marc 29.08.2024 08:13

какую область вы используете для генерации токена? Вы ищете часть кода или уже пробовали какой-либо код? Пожалуйста, укажите, если таковые имеются, отредактировав свой вопрос

Sridevi 29.08.2024 08:15

Я отредактировал вопрос с кодом.

Marc 29.08.2024 08:23
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
53
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Чтобы создать токен с помощью OAuth для настольного приложения (C# WinForms .NET Framework 4.8), вам необходимо переключиться на поток делегированной проверки подлинности, например интерактивный поток.

Для интерактивного потока обязательно добавьте URI перенаправления как http://localhost на платформе Mobile & desktop applications и включите опцию общедоступного клиентского потока при регистрации приложения, как показано ниже:

В моем случае я создал одно настольное приложение (C# WinForms .NET Framework 4.8) и использовал приведенные ниже примеры файлов кода для создания токена:

ОАутхелпер.cs:

using System.Linq;
using System.Threading.Tasks;
using Microsoft.Identity.Client;

namespace OAuthWinFormsApp
{
    public class OAuthHelper
    {
        private static readonly string[] Scopes = new string[]
        {
            "https://outlook.office.com/IMAP.AccessAsUser.All",
            "https://outlook.office.com/SMTP.Send",
            "https://outlook.office.com/User.Read"
        };

        private IPublicClientApplication _pca;

        public OAuthHelper(string clientId, string tenantId)
        {
            _pca = PublicClientApplicationBuilder.Create(clientId)
                .WithAuthority(AzureCloudInstance.AzurePublic, tenantId)
                .WithRedirectUri("http://localhost")
                .Build();
        }

        public async Task<string> GetAccessTokenAsync()
        {
            AuthenticationResult result = null;

            try
            {
                var accounts = await _pca.GetAccountsAsync();
                result = await _pca.AcquireTokenSilent(Scopes, accounts.FirstOrDefault())
                    .ExecuteAsync();
            }
            catch (MsalUiRequiredException)
            {
                result = await _pca.AcquireTokenInteractive(Scopes)
                    .WithPrompt(Prompt.SelectAccount)
                    .ExecuteAsync();
            }

            return result.AccessToken;
        }
    }
}

Форма1.cs:

using System;
using System.Windows.Forms;

namespace OAuthWinFormsApp
{
    public partial class Form1 : Form
    {
        private OAuthHelper _oauthHelper;

        public Form1()
        {
            InitializeComponent();
            _oauthHelper = new OAuthHelper("appId", "tenantId");
        }


        private async void btnAuthenticate_Click(object sender, EventArgs e)
        {
            try
            {
                string token = await _oauthHelper.GetAccessTokenAsync();
                txtToken.Text = token;
            }
            catch (Exception ex)
            {
                MessageBox.Show($"Error: {ex.Message}", "Authentication Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void txtToken_TextChanged(object sender, EventArgs e)
        {

        }
    }
}

Выход:

Когда я декодировал токен на веб-сайте jwt.ms, он имеет значения утверждений aud и scp, как показано ниже:

Круто!! Я проверил подлинность учетной записи в модальном окне, но думаю, что в приложении Azure произошла неправильная конфигурация, поскольку оно выдает ошибку. Сейчас я не могу управлять Azure, но через несколько дней я рассмотрю это у администратора.

Marc 30.08.2024 08:43

Пожалуйста, задайте новый вопрос с более подробной информацией и поделитесь ссылкой здесь, если ошибка все еще сохраняется :)

Sridevi 30.08.2024 13:44

Другие вопросы по теме