我正在努力在WinForms应用程序中添加cefsharp。我们的网站使用基本身份验证进行访问,但CefSharp不会显示该弹出窗口。我发现了this和this,但Visual Studio没有实现该接口,并抱怨AuthDialog是一个未知的类。我来自Java方面,对Winforms中的类不太了解,但我找不到AuthDialog。我究竟做错了什么?
代码:
bool IRequestHandler.GetAuthCredentials(IWebBrowser browser, bool isProxy, string host, int port,
string realm, string scheme, ref string username, ref string password)
{
//NOTE: If you do not wish to implement this method returning false is the default behaviour
// We also suggest you explicitly Dispose of the callback as it wraps an unmanaged resource.
// shyam - original implemenation.
//callback.Dispose();
//return false;
bool handled = false;
// Instantiate the dialog box
AuthDialog dlg = new AuthDialog(host); // create new dialog with username and password field.
// Open the dialog box modally
dlg.ShowDialog();
if (dlg.DialogResult == System.Windows.Forms.DialogResult.OK)
{
// The user did not cancel out of the dialog. Retrieve the username and password.
callback.Continue(dlg.UserName, dlg.Password);
handled = true;
}
return handled;
}
截图:
答案 0 :(得分:1)
您需要通过nuget packager添加对CefSharp的引用。您可以从Tools -> Nuget package manger
打开nuget包控制台。然后运行以下命令:
Install-Package CefSharp.WinForms -Version 63.0.3
添加完毕后,您就可以访问相关的课程了。
对于AuthDialog,我假设您在应用程序的某处创建了一个表单。需要添加名称空间。如果没有这样的表单,您将需要创建一个用户可以提供用户名和密码的表单。
答案 1 :(得分:1)
对我有用的解决方案:
public class MyRequestHandler : IRequestHandler
{
private string userName;
private string password;
public MyRequestHandler(string userName, string password)
{
this.userName = userName;
this.password = password;
}
//public static readonly string VersionNumberString = String.Format("Chromium: {0}, CEF: {1}, CefSharp: {2}",
// Cef.ChromiumVersion, Cef.CefVersion, Cef.CefSharpVersion);
bool IRequestHandler.OnBeforeBrowse(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, bool isRedirect)
{
return false;
}
bool IRequestHandler.OnOpenUrlFromTab(IWebBrowser browserControl, IBrowser browser, IFrame frame, string targetUrl, WindowOpenDisposition targetDisposition, bool userGesture)
{
return OnOpenUrlFromTab(browserControl, browser, frame, targetUrl, targetDisposition, userGesture);
}
protected virtual bool OnOpenUrlFromTab(IWebBrowser browserControl, IBrowser browser, IFrame frame, string targetUrl, WindowOpenDisposition targetDisposition, bool userGesture)
{
return false;
}
bool IRequestHandler.OnCertificateError(IWebBrowser browserControl, IBrowser browser, CefErrorCode errorCode, string requestUrl, ISslInfo sslInfo, IRequestCallback callback)
{
//NOTE: If you do not wish to implement this method returning false is the default behaviour
// We also suggest you explicitly Dispose of the callback as it wraps an unmanaged resource.
//callback.Dispose();
//return false;
//NOTE: When executing the callback in an async fashion need to check to see if it's disposed
//if (!callback.IsDisposed)
//{
// using (callback)
// {
// //To allow certificate
// //callback.Continue(true);
// //return true;
// }
//}
return false;
}
void IRequestHandler.OnPluginCrashed(IWebBrowser browserControl, IBrowser browser, string pluginPath)
{
// TODO: Add your own code here for handling scenarios where a plugin crashed, for one reason or another.
}
CefReturnValue IRequestHandler.OnBeforeResourceLoad(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IRequestCallback callback)
{
//Example of how to set Referer
// Same should work when setting any header
// For this example only set Referer when using our custom scheme
//var url = new Uri(request.Url);
//if (url.Scheme == CefSharpSchemeHandlerFactory.SchemeName)
//{
// //Referrer is now set using it's own method (was previously set in headers before)
// request.SetReferrer("http://google.com", ReferrerPolicy.Default);
//}
//Example of setting User-Agent in every request.
//var headers = request.Headers;
//var userAgent = headers["User-Agent"];
//headers["User-Agent"] = userAgent + " CefSharp";
//request.Headers = headers;
//NOTE: If you do not wish to implement this method returning false is the default behaviour
// We also suggest you explicitly Dispose of the callback as it wraps an unmanaged resource.
//callback.Dispose();
//return false;
//NOTE: When executing the callback in an async fashion need to check to see if it's disposed
//if (!callback.IsDisposed)
//{
// using (callback)
// {
// if (request.Method == "POST")
// {
// using (var postData = request.PostData)
// {
// if (postData != null)
// {
// var elements = postData.Elements;
// var charSet = request.GetCharSet();
// foreach (var element in elements)
// {
// if (element.Type == PostDataElementType.Bytes)
// {
// var body = element.GetBody(charSet);
// }
// }
// }
// }
// }
// //Note to Redirect simply set the request Url
// //if (request.Url.StartsWith("https://www.google.com", StringComparison.OrdinalIgnoreCase))
// //{
// // request.Url = "https://github.com/";
// //}
// //Callback in async fashion
// //callback.Continue(true);
// //return CefReturnValue.ContinueAsync;
// }
//}
return CefReturnValue.Continue;
}
bool IRequestHandler.GetAuthCredentials(IWebBrowser browserControl, IBrowser browser, IFrame frame, bool isProxy, string host, int port, string realm, string scheme, IAuthCallback callback)
{
//NOTE: If you do not wish to implement this method returning false is the default behaviour
// We also suggest you explicitly Dispose of the callback as it wraps an unmanaged resource.
callback.Continue(userName, password);
return true;
}
void IRequestHandler.OnRenderProcessTerminated(IWebBrowser browserControl, IBrowser browser, CefTerminationStatus status)
{
// TODO: Add your own code here for handling scenarios where the Render Process terminated for one reason or another.
// browserControl.Load(CefExample.RenderProcessCrashedUrl);
}
bool IRequestHandler.OnQuotaRequest(IWebBrowser browserControl, IBrowser browser, string originUrl, long newSize, IRequestCallback callback)
{
//NOTE: If you do not wish to implement this method returning false is the default behaviour
// We also suggest you explicitly Dispose of the callback as it wraps an unmanaged resource.
//callback.Dispose();
//return false;
//NOTE: When executing the callback in an async fashion need to check to see if it's disposed
//if (!callback.IsDisposed)
//{
// using (callback)
// {
// //Accept Request to raise Quota
// //callback.Continue(true);
// //return true;
// }
//}
return false;
}
bool IRequestHandler.OnProtocolExecution(IWebBrowser browserControl, IBrowser browser, string url)
{
return url.StartsWith("mailto");
}
void IRequestHandler.OnRenderViewReady(IWebBrowser browserControl, IBrowser browser)
{
}
bool IRequestHandler.OnResourceResponse(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response)
{
//NOTE: You cannot modify the response, only the request
// You can now access the headers
//var headers = response.ResponseHeaders;
return false;
}
IResponseFilter IRequestHandler.GetResourceResponseFilter(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response)
{
//var url = new Uri(request.Url);
//if (url.Scheme == CefSharpSchemeHandlerFactory.SchemeName)
//{
// if (request.Url.Equals(CefExample.ResponseFilterTestUrl, StringComparison.OrdinalIgnoreCase))
// {
// return new FindReplaceResponseFilter("REPLACE_THIS_STRING", "This is the replaced string!");
// }
// if (request.Url.Equals("custom://cefsharp/assets/js/jquery.js", StringComparison.OrdinalIgnoreCase))
// {
// return new AppendResponseFilter(System.Environment.NewLine + "//CefSharp Appended this comment.");
// }
// return new PassThruResponseFilter();
//}
return null;
}
void IRequestHandler.OnResourceLoadComplete(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response, UrlRequestStatus status, long receivedContentLength)
{
}
public bool OnSelectClientCertificate(IWebBrowser browserControl, IBrowser browser, bool isProxy, string host, int port, X509Certificate2Collection certificates, ISelectClientCertificateCallback callback)
{
return false;
}
public void OnResourceRedirect(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response, ref string newUrl)
{
}
}
并在Chrome浏览器中调用它,如下所示:
private void InitializeChromium()
{
chromiumBrowser = new ChromiumWebBrowser("https://www.google.com")
{
Dock = DockStyle.Fill,
};
chromiumBrowser.RequestHandler = new MyRequestHandler("actual_username","actual_password");
this.Controls.Add(chromiumBrowser);
}
答案 2 :(得分:0)
以下解决方案对我有用。 我创建了一个新类,该类继承了RequestHandler类,并添加了一个自定义对话框来输入用户凭据。如果输入的详细信息没有权限/授权,则弹出窗口将显示无效的凭据。
public class MyRequestHandler : RequestHandler
{
private string userName;
private string password;
private string ValidationMessage = string.Empty;
protected override bool GetAuthCredentials(IWebBrowser chromiumWebBrowser, IBrowser browser, string originUrl, bool isProxy, string host, int port, string realm, string scheme, IAuthCallback callback)
{
userName = Environment.UserDomainName + @"\" + Environment.UserName;
if (!Getcredentials(ref userName, ref password))
{
AllowCredentials dlg = new AllowCredentials();
dlg.Topmost = true;
dlg.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterScreen;
dlg.textBlock.Text = userName;
dlg.InvalidCredentials.Content = ValidationMessage;
dlg.ShowDialog();
if (dlg.SetCredentials == true)
{
password = dlg.txtPassword.Password;
//to check if the site is accessible with the login credentials
if (IsCredentialsValid(userName, password, originUrl))
{
callback.Continue(userName, password);
SaveWindowsCredentials(userName, password);
ValidationMessage = string.Empty;
}
else { ValidationMessage = "Invalid Credentials"; callback.Continue(string.Empty, string.Empty); }
}
else
{
return false;
}
}
else
{
if (IsCredentialsValid(userName, password, originUrl))
{
callback.Continue(userName, password);
}
else { ValidationMessage = "Invalid Credentials"; callback.Continue(string.Empty, string.Empty); }
}
return true;
}
private void SaveWindowsCredentials(string UserName, string Password)
{
try
{
using (Credential cred = new Credential())
{
cred.Password = password;
cred.Target = UserName;
cred.Username = UserName;
cred.Type = CredentialType.Generic;
cred.PersistanceType = PersistanceType.Enterprise;
cred.Save();
}
}
catch (System.Exception)
{
throw;
}
}
private bool Getcredentials(ref string UserName, ref string Password)
{
try
{
using (Credential cred = new Credential())
{
cred.Target = UserName;
cred.Username = UserName;
cred.Load();
Password = cred.Password;
}
if (string.IsNullOrEmpty(Password)) { return false; }
else
{
return true;
}
}
catch (System.Exception)
{
throw;
}
}
private bool IsCredentialsValid(string UserName, string Password, string URL)
{
try
{
var request = WebRequest.Create(URL);
request.Credentials = new System.Net.NetworkCredential(UserName, Password);
var response = request.GetResponse();
if (response.IsMutuallyAuthenticated) { return true; }
else
{
return false;
}
}
catch (Exception)
{
return false;
}
}
}