在使用CefSharp处理身份验证请求时,如何在关闭时修复无限对话循环
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在使用CefSharp处理身份验证请求时,如何在关闭时修复无限对话循环相关的知识,希望对你有一定的参考价值。
因此,我正在制作的应用程序需要处理网页发送的身份验证请求,以便登录并使用该页面。为了实现这一点,我在一些研究后发现,我应该实现CefSharp的IRequestHandler接口,并使用名为“GetAuthCredentials”的方法打开一个对话框,并从这里请求用户名和密码。
这一切似乎工作正常,我能够使用正确的凭据登录到页面。但是,当我尝试通过此方法登录网站后关闭我的整个应用程序时,应用程序冻结并拒绝关闭。它似乎关闭了窗体上的浏览器控件,但不关闭窗体本身。
当我不必使用登录时,我可以正常关闭应用程序而没有任何问题,但每当我执行上述场景时,除了在Taskmanager中结束任务之外我无法关闭它。
我怀疑“GetAuthCredentials”从未真正处理过,或者一直反复请求对话,导致无限循环使我的应用程序无法关闭。但是我无法找到这个问题的根源。
使用“GetAuthCredentials”的Requesthandler实现:
class RequestEventHandler : IRequestHandler
{
bool IRequestHandler.GetAuthCredentials(IWebBrowser browserControl, IBrowser browser, IFrame frame, bool isProxy, string host, int port, string realm, string scheme, IAuthCallback callback)
{
bool handled = false;
AuthenticationDialog dlg = new AuthenticationDialog(host);
dlg.ShowDialog();
if (dlg.DialogResult == System.Windows.Forms.DialogResult.OK)
{
callback.Continue(dlg.UserName, dlg.Password);
handled = true;
}
return handled;
}
它打开的Dialogform:
public partial class AuthenticationDialog : Form
{
internal string UserName { get; set; }
internal string Password { get; set; }
public AuthenticationDialog(string Hostname)
{
InitializeComponent();
Lbl_WebUrl.Text = Hostname;
}
private void Btn_SignIn_Click(object sender, EventArgs e)
{
if(Tbx_Username.TextLength > 0 && Tbx_Password.TextLength > 0)
{
UserName = Tbx_Username.Text;
Password = Tbx_Password.Text;
}
else if (Tbx_Username.TextLength == 0 && Tbx_Password.TextLength > 0)
{
Lbl_Error.Text = SetError(1);
}
else if (Tbx_Username.TextLength > 0 && Tbx_Password.TextLength == 0)
{
Lbl_Error.Text = SetError(2);
}
else
{
Lbl_Error.Text = SetError(0);
}
}
此处的登录按钮将Dialog_Result属性设置为Dialogresult.OK
关闭应用程序的方法:(位于包含浏览器的mainform中)
private void btn_ApplicationClose_Click(object sender, EventArgs e)
{
browser.Dispose();
Cef.Shutdown();
Application.Exit();
}
任何关于这个问题的建议或解决方案都会非常感激,这个问题已经磨了几天了。
更新:根据@amaitland的建议,我使用以下代码在UI线程上打开了对话框:
bool IRequestHandler.GetAuthCredentials(IWebBrowser browserControl, IBrowser browser, IFrame frame, bool isProxy, string host, int port, string realm, string scheme, IAuthCallback callback)
{
bool handled = false;
ChromiumWebBrowser b = browserControl as ChromiumWebBrowser;
b.BeginInvoke((MethodInvoker)delegate
{
AuthenticationDialog dlg = new AuthenticationDialog(host);
dlg.ShowDialog();
if (dlg.DialogResult == System.Windows.Forms.DialogResult.OK)
{
callback.Continue(dlg.UserName, dlg.Password);
handled = true;
}
});
return handled;
这似乎有效,让我的应用程序在使用登录时关闭,但是现在似乎无法处理登录信息。登录时,它关闭对话框,似乎没有对我给出的凭据做任何事情。
我错过了什么或者我的实施错了吗?
因此,通过@amaitland的一些有用的建议,我已经能够解决我的问题,导致下面的代码用于RequestHandler的GetAuthCredentials
方法。
bool IRequestHandler.GetAuthCredentials(IWebBrowser browserControl, IBrowser browser, IFrame frame, bool isProxy, string host, int port, string realm, string scheme, IAuthCallback callback)
{
ChromiumWebBrowser b = browserControl as ChromiumWebBrowser; //casts the given browsercontrol as chromiumwebbrowser, to acces the .beginInvoke method
b.BeginInvoke((MethodInvoker)delegate
{
//creates an instance of the authentication dialog to get the user credentials
AuthenticationDialog dlg = new AuthenticationDialog(host);
dlg.ShowDialog();
if (dlg.DialogResult == System.Windows.Forms.DialogResult.OK) //if the sign-in button is clicked
{
callback.Continue(dlg.UserName, dlg.Password);
}
else // if the close or cancel button on field is clicked
{
callback.Cancel();
}
});
return true;
}
在这里,我使用.BeginInvoke()
在UI线程而不是主线程上打开对话框,并确保请求将在处理时使用处理。这解决了我使用它的所有问题,它可能会给出一个示例来实现您自己的RequestHandler for GetAuthCredentials
。
以上是关于在使用CefSharp处理身份验证请求时,如何在关闭时修复无限对话循环的主要内容,如果未能解决你的问题,请参考以下文章
如何在不丢失身份验证的情况下模拟Session.request?