Window 在 Unity3D 中使用 MSAL .NET 库时不显示提示

Window prompt not showing when using MSAL .NET library in Unity3D

我正在尝试通过 MSAL 库 (Microsoft Identity Platform) 使用我的 Unity 应用登录 SharePoint。当我第一次 运行 时,我根本没有看到弹出窗口,也没有错误。 (注意,我已经在编辑器中尝试过并作为独立的 exe)

但是,在 运行 第二次之后,我确实注意到,我收到一个名为 Oops 的弹出窗口 window,其中包含消息 Could not register the window class win32 error 0。经过一些谷歌搜索后,我认为这可能是因为在第一次尝试后我需要以某种方式清理后台某处的某种悬挂 window 。如果我重新启动 Unity,我可以再次 运行,第一次没有错误,但再次没有弹出窗口 window。如果我第二次 运行,当然,我会再次收到 Oops 消息。

可能无关但值得注意的是,如果我在 Oops window 上点击“确定”,我会得到一个空异常错误。 AcquireTokenInteractive 似乎正在尝试打开一个失败的 window,将其保留为 null,然后尝试从 null 中获取令牌。

任何有助于找出 window 未出现的原因的建议都将不胜感激

using Microsoft.Identity.Client;

public class MyApp: MonoBehaviour
{
    private string ClientId = "i-am-not-telling";
    private string Tenant = "common";

    void Start()
    {
        SharepointLogin();
    }

    public async void SharepointLogin()
    {
        PublicClientApp = PublicClientApplicationBuilder.Create(ClientId)
                .WithRedirectUri("https://login.microsoftonline.com/common/oauth2/nativeclient")
                .WithAuthority(AzureCloudInstance.AzurePublic, Tenant)
                .Build();
        IEnumerable<string> scopes = new List<string> { "User.Read" };
        AuthenticationResult result;
        result = await PublicClientApp.AcquireTokenInteractive(scopes)
                        .ExecuteAsync();
    }
}

您是否尝试过将父 window 提供给 Builder?在 Unity 中,获取 Window 句柄有点困难,但这段代码可能有效,并可能解决问题。

[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern System.IntPtr GetActiveWindow();

public static System.IntPtr GetWindowHandle() {
  return GetActiveWindow();
}

然后用WithParentActivityOrWindow

调用
public async void SharepointLogin()
{
    PublicClientApp = PublicClientApplicationBuilder.Create(ClientId)
        .WithRedirectUri("https://login.microsoftonline.com/common/oauth2/nativeclient")
        .WithAuthority(AzureCloudInstance.AzurePublic, Tenant)
        .WithParentActivityOrWindow(GetWindowHandle)
        .Build();
    IEnumerable<string> scopes = new List<string> { "User.Read" };
    AuthenticationResult result;
    result = await PublicClientApp.AcquireTokenInteractive(scopes)
        .ExecuteAsync();
}

我认为这是 Unity 或 MSAL 库之间的错误。我将向两者提交错误报告并等待修复。这种方法暂时行不通。我将不得不使用不同的方法进行身份验证。

来自 Unity 的更新: 问题出在Unity中我们不支持的System.Windows.Forms。在可预见的未来,这种行为似乎不会改变。在论坛上,我读到将 System.Windows.Forms.dll 添加到插件文件夹对一些用户有帮助,但 MSAL 似乎并非如此。即使有效,我们也不对任何崩溃或错误负责。

我的更新: 我完全放弃了这个方法并使用了代码 。到目前为止,它仅在“本地”SharePoint 站点上取得成功,我正在尝试获得支持以使用“SharePoint Online”服务器。如果您没有我可能面临的相同代理问题,可能会为其他人工作。

我发现需要确保在后台线程中调用交互式浏览器调用。然后它按预期工作。

Task.Factory.StartNew(() =>await app.AcquireTokenInteractive(STORAGE_SCOPES).ExecuteAsync());