无法使用网络级别身份validation向远程桌面服务器提供正确的凭据后,防止登录尝试失败窗口

我正在使用“Microsoft终端服务控件类型库”建立与远程桌面服务器的连接。 我正在寻找一种方法来防止或抑制在连接到使用网络级别身份validation(NLA)的远程桌面服务器时未能提供正确的用户名/密码组合时显示的“Windows安全”提示。 窗口看起来像这样:

在此处输入图像描述

我已经阅读并尝试了我现在可以在网上找到的所有设置组合,但没有一个成功。 以下是我在stackoverlow上发现的一些问题,这些问题谈论了这个确切的问题并且据说可以解决但是答案对我不起作用:

AxMsRdpClient9关闭登录对话框

AxMsRdpClient6NotSafeForScripting AllowPromptingForCredentials

这可能听起来很荒谬,但我的最终目标只是尝试连接到rdp服务器并故意输入无效的用户名/密码,然后在失败时断开连接。 我不关心实际连接或显示任何东西。 如果这很重要,我这样做是为了尝试在远程服务器上的事件日志中触发失败的登录尝试,而另一个应用程序稍后将使用该日志。

下面的代码已经触发了事件日志中失败的登录尝试,但我找不到阻止这个失败的登录框弹出客户端机器的方法,我宁愿不诉诸于试图关闭窗口的黑客打开。 当远程桌面服务器配置为允许来自运行任何版本的远程桌面的计算机的连接(安全性较低的选项)时,我没有同样的问题,因为弹出提示显然是NLA提供的额外安全性的一部分。

我已经为这个控件尝试了很多不同的设置组合,我的脑袋正在旋转。 以下是一个模仿上述其他stackoverflow问题之一的示例:

Public Class Form1 Dim WithEvents oRemote As AxMSTSCLib.AxMsRdpClient6NotSafeForScripting Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load oRemote = New AxMSTSCLib.AxMsRdpClient6NotSafeForScripting CType(oRemote, System.ComponentModel.ISupportInitialize).BeginInit() oRemote.Dock = System.Windows.Forms.DockStyle.Fill oRemote.Enabled = True oRemote.Name = "OfficeWin7" Me.Controls.Add(oRemote) CType(oRemote, System.ComponentModel.ISupportInitialize).EndInit() oRemote.CreateControl() oRemote.Size = New System.Drawing.Size(800, 600) oRemote.Server = "IPADDRESS" oRemote.UserName = "TestAccount" oRemote.AdvancedSettings7.ClearTextPassword = "WrongPassword" Dim ocx As MSTSCLib.IMsRdpClientNonScriptable4 = oRemote.GetOcx() ocx.EnableCredSspSupport = True ocx.AllowCredentialSaving = False ocx.PromptForCredentials = False ocx.PromptForCredsOnClient = False oRemote.Connect() End Sub Private Sub oRemote_OnAuthenticationWarningDismissed(sender As Object, e As EventArgs) Handles oRemote.OnAuthenticationWarningDismissed MessageBox.Show("The credentials popup is now closing") End Sub Private Sub oRemote_OnAuthenticationWarningDisplayed(sender As Object, e As EventArgs) Handles oRemote.OnAuthenticationWarningDisplayed MessageBox.Show("The credentials popup is about to be shown") End Sub End Class 

据说是ocx.PromptForCredentials = False行应该阻止这个弹出窗口,但如果该值设置为TrueFalse ,它似乎没有区别。 我几乎可以通过属性名称假设ocx.PromptForCredsOnClient可能实际工作,但同样,我将该值设置为没有区别。 我总是得到相同的弹出窗口。

在这一点上我不知道我做错了什么,但我的直觉告诉我,为了使这个工作,我需要实例化基础AxMsRdpClient6NotSafeForScripting对象,如AxMsRdpClient9NotSafeForScripting甚至AxMsTscAxNotSafeForScripting ,这是控件在我删除它时使用的默认类型在表格上。 我已经尝试了很多这些设置组合,但我希望有人可以对这种情况有所了解。

我还应该提到我对使用.Net连接到远程桌面服务器的替代方法持开放态度,如果有的话,不涉及使用Microsoft Terminal Services Control Type Library 。 如果他们确实存在,我没有太多运气找到他们,但如果我在搜索中遗漏了任何内容,请告诉我。

编辑:为了确保您自己的服务器设置与我的相同或相似,只需要满足两个要求:

  1. 远程桌面必须在Vista或更新版本的Windows上运行
  2. 必须将远程桌面设置为使用NLA。 在Win7中,确切的选项文本是:“仅允许来自运行具有网络级别身份validation的远程桌面的计算机的连接(更安全)”

此时,我不关心您在代码中更改的选项,只要服务器在您尝试连接时记录失败的登录,并且凭据框(或任何其他弹出窗口)永远不会出现在客户端。

看来,添加此代码所需的正确引用的最简单方法是将“Microsoft终端服务控件”从COM选项卡添加到工具箱,然后将“Microsoft RDP客户端控件”放到表单上。 更多信息请访问: http : //s.codeproject.com/Articles/43705/Remote-Desktop-using-C-NET

以下是C#中的相同代码,以便使这个问题更受欢迎:

 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace WindowsFormsApplication1 { public partial class Form1 : Form { private AxMSTSCLib.AxMsRdpClient6NotSafeForScripting withEventsField_oRemote; public AxMSTSCLib.AxMsRdpClient6NotSafeForScripting oRemote { get { return withEventsField_oRemote; } set { if (withEventsField_oRemote != null) { withEventsField_oRemote.OnAuthenticationWarningDismissed -= oRemote_OnAuthenticationWarningDismissed; withEventsField_oRemote.OnAuthenticationWarningDisplayed -= oRemote_OnAuthenticationWarningDisplayed; } withEventsField_oRemote = value; if (withEventsField_oRemote != null) { withEventsField_oRemote.OnAuthenticationWarningDismissed += oRemote_OnAuthenticationWarningDismissed; withEventsField_oRemote.OnAuthenticationWarningDisplayed += oRemote_OnAuthenticationWarningDisplayed; } } } private void Form1_Load(object sender, EventArgs e) { oRemote = new AxMSTSCLib.AxMsRdpClient6NotSafeForScripting(); ((System.ComponentModel.ISupportInitialize)oRemote).BeginInit(); oRemote.Dock = System.Windows.Forms.DockStyle.Fill; oRemote.Enabled = true; oRemote.Name = "OfficeWin7"; this.Controls.Add(oRemote); ((System.ComponentModel.ISupportInitialize)oRemote).EndInit(); oRemote.CreateControl(); oRemote.Size = new System.Drawing.Size(800, 600); oRemote.Server = "IPADDRESS"; oRemote.UserName = "TestAccount"; oRemote.AdvancedSettings7.ClearTextPassword = "WrongPassword"; MSTSCLib.IMsRdpClientNonScriptable4 ocx = (MSTSCLib.IMsRdpClientNonScriptable4)oRemote.GetOcx(); ocx.EnableCredSspSupport = true; ocx.AllowCredentialSaving = false; ocx.PromptForCredentials = false; ocx.PromptForCredsOnClient = false; oRemote.Connect(); } private void oRemote_OnAuthenticationWarningDismissed(object sender, EventArgs e) { MessageBox.Show("The credentials popup is now closing"); } private void oRemote_OnAuthenticationWarningDisplayed(object sender, EventArgs e) { MessageBox.Show("The credentials popup is about to be shown"); } public Form1() { Load += Form1_Load; } } } 

首先,您确实需要确保您的测试环境使用RDP的最新更新,特别是如果它是Windows 7 – 只需运行Windows Update。

接下来,关注这一行:

  ocx.EnableCredSspSupport = True 

它正在启用安全支持提供商 。 我不是这方面的专家,但可能有一个内部例程说:

Load locally stored credentials; if there aren't such - ask the user then crypt, hash, bla-bla, and store them locally, in order to use them next time

此时会弹出询问凭据的对话框。 我不认为你可以影响这种行为,但幸运的是,你可以影响提供者是否在图片中发生。 所以将其设置为False ,看看会发生什么。