桌面应用程序中的 Azure 身份验证流程 (WinForms C#)

问题描述 投票:0回答:1

我将使用桌面应用程序的 OAuth (C# WinForms .NET Framework 4.8) 通过 Azure 上的 SMTP 发送邮件(并通过 IMAP 读取)。该帐户具有 MFA,但不是 Windows 帐户。我读过一些文章、主题和示例,但没有人适用,并且如果应用程序不是 Web,则似乎不可能完成用户身份验证流程以获取帐户的令牌。

以下代码有效,但我无法获取特定帐户的 accessToken:

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 身份验证流程,但在桌面应用程序中,我不知道该怎么做。

c# azure oauth multi-factor-authentication
1个回答
0
投票

要使用 OAuth 为桌面应用程序 (C# WinForms .NET Framework 4.8) 生成令牌,您需要切换到委托身份验证流程,如交互流程。

对于交互式流程,请确保在

Mobile & desktop applications
平台中将重定向 URI 添加为 http://localhost,并在应用程序注册中添加 enable 公共客户端流程选项,如下所示:

enter image description here

就我而言,我创建了一个桌面应用程序(C# WinForms .NET Framework 4.8)并使用以下示例代码文件来生成令牌:

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

Form1.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)
        {

        }
    }
}

输出:

enter image description here

当我在 jwt.ms 网站中解码令牌时,它具有

aud
scp
声明值,如下所示:

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.