问题
I am using the 'Microsoft Terminal Services Control Type Library' to establish a connection to a remote desktop server. I am looking for a way to prevent or suppress the 'Windows Security' prompt that is displayed when failing to provide a proper username/password combination when connecting to a remote desktop server that uses Network Level Authentication (NLA). The window looks something like this:
I have read about and tried every combination of settings that I can find online at this time and none of them have been successful. Here are a couple of the questions I found on stackoverlow that talk about this exact issue and supposedly get it resolved but the answers are not working for me:
AxMsRdpClient9 Dismiss login dialog
AxMsRdpClient6NotSafeForScripting AllowPromptingForCredentials
It may sound ridiculous but my ultimate goal is just to attempt connecting to an rdp server and purposely enter an invalid username/password and then disconnect when it fails. I do not care about actually connecting or displaying anything. If it matters, I am doing this in an attempt to trigger a failed logon attempt in the event logs on the remote server which another app will make use of later.
The code below already triggers a failed logon attempt in the event logs but I just cannot find a way to stop this failed logon box from popping up on the client machine and I would rather not resort to hacks that attempt to close the window after it is open. When the remote desktop server is configured to allow connections from computers running any version of remote desktop (less secure option) I do not have this same problem as the popup prompt is obviously part of the extra security that NLA offers.
I have already tried so many different combinations of settings for this control that my head is spinning. Here is one example that is modeled after one of the other stackoverflow questions above:
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
Supposedly it is the ocx.PromptForCredentials = False
line that should prevent this popup but it doesn't seem to make a difference if that value is set to True
or False
. I would almost assume by the property name that ocx.PromptForCredsOnClient
might actually work, but again, it doesn't make a difference what I set that value to. I always get the same popup.
At this point I have no idea what I am doing wrong but my gut tells me that to get this working I need to instantiate the base AxMsRdpClient6NotSafeForScripting
object as something else like AxMsRdpClient9NotSafeForScripting
or even AxMsTscAxNotSafeForScripting
which is the default type the control uses when I drop it onto a form. I have already tried a bunch of these combinations of settings however and am hoping someone can shed some light on the situation.
I should also mention I am open to alternative methods of connecting to a remote desktop server using .Net that don't involve using the Microsoft Terminal Services Control Type Library
if there are any. I didn't have much luck finding them if they do exist but please let me know if I missed anything in my search.
Edit: To ensure that your own server is set up the same or similar to mine there are only two requirements that need to be met:
- Remote Desktop must be running on a version of windows that is Vista or newer
- Remote desktop must be set to use NLA. In Win7 the exact option text is: 'Allow connections only from computers running Remote Desktop with Network Level Authentication (more secure)'
At that point I don't care what options you change in the code as long as the server logs a failed login when you attempt to connect and the credentials box (or any other popups) never appear on the client side.
It appears that the easiest way to add the proper references that this code needs is to add the 'Microsoft Terminal Services control' from the COM tab to your toolbox and then drop a 'Microsoft RDP Client Control' onto a form. More information here: http://s.codeproject.com/Articles/43705/Remote-Desktop-using-C-NET
Here is the same code in C# in case that makes this question more popular:
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;
}
}
}
回答1:
First off, you really need to make sure your test environment uses the latest update for RDP, especially if it's Windows 7 - just run Windows Update.
Next, focus on this line:
ocx.EnableCredSspSupport = True
It is enabling a security support provider. I'm not an expert in the matter, but probably there is an internal routine saying:
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
At this point the dialog, asking for credentials is popped up. I don't think you can influence this behavior, but, fortunately you can influence whether the provider takes place in the picture or not. So set this to False
and see what happens.
来源:https://stackoverflow.com/questions/37669589/prevent-failed-logon-attempt-window-after-failing-to-supply-proper-credentials-t