You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi中使用MSAL库实现Azure AD带选账户提示的认证方案咨询

在Delphi中实现Azure AD认证(带select_account提示)的解决方案

一、解决当前C# COM DLL弹窗不显示的问题

你的核心问题是MSAL的UI交互窗口找不到正确的父窗口上下文,导致弹窗被隐藏或无法创建。可以通过以下两步修复:

1. 在COM接口中添加父窗口句柄参数

修改C#的COM类,新增接收窗口句柄的参数,将其传递给MSAL的认证方法:

[ComVisible(true)]
public interface IAzureAuth
{
    Task<string> Authenticate(IntPtr parentWindowHandle);
}

[ComVisible(true)]
public class AzureAuth : IAzureAuth
{
    public async Task<string> Authenticate(IntPtr parentWindowHandle)
    {
        var pca = PublicClientApplicationBuilder
            .Create("你的客户端ID")
            .WithAuthority("https://login.microsoftonline.com/你的租户ID")
            .WithParentWindowHandle(parentWindowHandle) // 传入Delphi窗口句柄
            .Build();

        var result = await pca.AcquireTokenInteractive(new[] { "user.read" })
            .WithPrompt(Prompt.SelectAccount) // 启用账户选择提示
            .ExecuteAsync();

        return result.AccessToken;
    }
}

2. Delphi调用时传递主窗口句柄

在Delphi中调用COM方法时,传入主窗口的Handle,确保MSAL能找到正确的UI上下文:

var
  AzureAuth: IAzureAuth;
  AccessToken: string;
begin
  AzureAuth := CoAzureAuth.Create;
  // 传递主窗口句柄,确保弹窗正常显示
  AccessToken := AzureAuth.Authenticate(Application.MainForm.Handle);
end;

另外需要注意:确保Delphi的调用线程是STA(单线程单元)模型,UI交互必须在STA线程中执行,避免线程上下文不一致导致的弹窗问题。

二、更优的Delphi原生实现方案

如果不想依赖.NET COM,可以直接基于Azure AD的OAuth2.0 REST API实现,完全原生适配Delphi环境:

1. 授权码流程(带select_account提示)

步骤如下:

  • 构造包含prompt=select_account参数的授权URL,通过ShellExecute打开默认浏览器让用户选择账户并授权
  • 启动本地HTTP监听服务,接收Azure AD回调的授权码
  • 用授权码向token端点请求access token和refresh token

核心代码片段:

var
  AuthURL: string;
  TenantID, ClientID: string;
begin
  TenantID := '你的租户ID';
  ClientID := '你的客户端ID';
  
  // 构造授权URL,强制显示账户选择界面
  AuthURL := 'https://login.microsoftonline.com/' + TenantID + '/oauth2/v2.0/authorize?' +
    'client_id=' + ClientID + '&' +
    'response_type=code&' +
    'redirect_uri=http://localhost:8080/callback&' +
    'scope=user.read&' +
    'prompt=select_account';

  // 打开浏览器跳转至授权页面
  ShellExecute(0, 'open', PChar(AuthURL), nil, nil, SW_SHOWNORMAL);

  // 此处需实现本地HTTP监听服务,获取回调中的授权码,再请求token
  // 可使用Indy的TIdHTTP组件处理后续token请求
end;

2. 第三方Delphi组件简化开发

可以使用支持OAuth2.0的Delphi组件(如Indy的OAuth2扩展、商业组件DevExpress的Auth组件等),这些组件已封装好授权流程、回调监听和token管理,能大幅减少自定义代码量。

内容的提问来源于stack exchange,提问作者user9106606

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 02:55:15