当页面重定向到 localhost 时未引发导航事件

Navigating Event Not Raised when a Page Redirects to localhost

提问人:John Saunders 提问时间:3/11/2014 更新时间:3/24/2018 访问量:2918

问:

我有一个使用 OAUTH 服务的 Windows 窗体应用程序。为了进行身份验证,我使用 Web 浏览器控件导航到服务的登录页面。用户输入用户名和密码,效果很好。

接下来,该服务将显示“授予访问权限”页面。当用户单击“授予访问权限”时,页面将重定向到我选择的 URL,并在查询字符串中传递身份验证令牌。

这在我开发的 Windows 7 机器上运行良好。我在 Navigating 事件中捕获查询字符串,隐藏 Web 浏览器控件,然后可以使用我收到的令牌来使用该服务。但在 Windows 8 和 Windows Server 2012 上,导航事件永远不会发生。相反,Web 浏览器控件显示 404 错误。

有没有办法捕获该重定向的结果?

P.S. 我尝试使用 HttpListener,它起作用了,但它需要管理员安装应用程序来设置 http 绑定。

.NET WinForms Web浏览器控件

评论

0赞 noseratio 3/11/2014
尝试在基础 WebBrowser ActiveX 上处理原始事件,如下所示。BeforeNavigate2
0赞 John Saunders 3/11/2014
@Noseratio:我试试看。与此同时,如果你要回答这个问题(以及WinForms),那么我会投赞成票。

答:

2赞 noseratio 3/11/2014 #1

尝试在基础 ActiveX 上处理原始 BeforeNavigate2 事件,下面是 WinForms 版本(基于原始 WPF 版本):WebBrowser

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace WindowsForms_22311110
{
    public partial class MainForm : Form
    {
        WebBrowser webBrowser;

        public MainForm()
        {
            InitializeComponent();

            this.webBrowser = new WebBrowser();
            this.webBrowser.Dock = DockStyle.Fill;
            this.Controls.Add(this.webBrowser);
            this.webBrowser.Visible = true;

            this.Load += MainForm_Load;
        }

        void MainForm_Load(object sender, EventArgs e)
        {
            // the below line makes sure the underlying ActiveX gets created
            if (this.webBrowser.Document != null || this.webBrowser.ActiveXInstance == null)
                throw new InvalidOperationException("webBrowser");

            var sink = new WebBrowserEventSink();
            sink.Connect(this.webBrowser);

            this.webBrowser.Navigate("http://example.com");            
        }
    }

    /// <summary>
    /// Handling WinForms WebBrowser ActiveX events directly
    /// this code depends on SHDocVw.dll COM interop assembly,
    /// generate SHDocVw.dll: "tlbimp.exe ieframe.dll",
    /// and add as a reference to the project
    ///
    /// by Noseratio - https://stackoverflow.com/a/22312476/1768303
    /// </summary>

    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.None)]
    [ComDefaultInterface(typeof(SHDocVw.DWebBrowserEvents2))]
    public class WebBrowserEventSink : SHDocVw.DWebBrowserEvents2
    {
        System.Runtime.InteropServices.ComTypes.IConnectionPoint _sinkCP = null;
        int _sinkCookie = int.MaxValue;

        public void Connect(WebBrowser webBrowser)
        {
            if (_sinkCookie != int.MaxValue)
                throw new InvalidOperationException();

            var activeXInstance = webBrowser.ActiveXInstance;

            var cpc = (System.Runtime.InteropServices.ComTypes.IConnectionPointContainer)activeXInstance;
            var guid = typeof(SHDocVw.DWebBrowserEvents2).GUID;

            cpc.FindConnectionPoint(ref guid, out _sinkCP);
            _sinkCP.Advise(this, out _sinkCookie);
        }

        public void Disconnect()
        {
            if (_sinkCookie == int.MaxValue)
                throw new InvalidOperationException();
            _sinkCP.Unadvise(_sinkCookie);
            _sinkCookie = int.MaxValue;
            _sinkCP = null;
        }

        #region SHDocVw.DWebBrowserEvents2

        public void StatusTextChange(string Text)
        {
        }

        public void ProgressChange(int Progress, int ProgressMax)
        {
        }

        public void CommandStateChange(int Command, bool Enable)
        {
        }

        public void DownloadBegin()
        {
        }

        public void DownloadComplete()
        {
        }

        public void TitleChange(string Text)
        {
        }

        public void PropertyChange(string szProperty)
        {
        }

        public void BeforeNavigate2(object pDisp, ref object URL, ref object Flags, ref object TargetFrameName, ref object PostData, ref object Headers, ref bool Cancel)
        {
            MessageBox.Show("BeforeNavigate2: " + URL.ToString());
        }

        public void NewWindow2(ref object ppDisp, ref bool Cancel)
        {
        }

        public void NavigateComplete2(object pDisp, ref object URL)
        {
        }

        public void DocumentComplete(object pDisp, ref object URL)
        {
        }

        public void OnQuit()
        {
        }

        public void OnVisible(bool Visible)
        {
        }

        public void OnToolBar(bool ToolBar)
        {
        }

        public void OnMenuBar(bool MenuBar)
        {
        }

        public void OnStatusBar(bool StatusBar)
        {
        }

        public void OnFullScreen(bool FullScreen)
        {
        }

        public void OnTheaterMode(bool TheaterMode)
        {
        }

        public void WindowSetResizable(bool Resizable)
        {
        }

        public void WindowSetLeft(int Left)
        {
        }

        public void WindowSetTop(int Top)
        {
        }

        public void WindowSetWidth(int Width)
        {
        }

        public void WindowSetHeight(int Height)
        {
        }

        public void WindowClosing(bool IsChildWindow, ref bool Cancel)
        {
        }

        public void ClientToHostWindow(ref int CX, ref int CY)
        {
        }

        public void SetSecureLockIcon(int SecureLockIcon)
        {
        }

        public void FileDownload(bool ActiveDocument, ref bool Cancel)
        {
        }

        public void NavigateError(object pDisp, ref object URL, ref object Frame, ref object StatusCode, ref bool Cancel)
        {
        }

        public void PrintTemplateInstantiation(object pDisp)
        {
        }

        public void PrintTemplateTeardown(object pDisp)
        {
        }

        public void UpdatePageStatus(object pDisp, ref object nPage, ref object fDone)
        {
        }

        public void PrivacyImpactedStateChange(bool bImpacted)
        {
        }

        public void NewWindow3(ref object ppDisp, ref bool Cancel, uint dwFlags, string bstrUrlContext, string bstrUrl)
        {
        }

        public void SetPhishingFilterStatus(int PhishingFilterStatus)
        {
        }

        public void WindowStateChanged(uint dwWindowStateFlags, uint dwValidFlagsMask)
        {
        }

        public void NewProcess(int lCauseFlag, object pWB2, ref bool Cancel)
        {
        }

        public void ThirdPartyUrlBlocked(ref object URL, uint dwCount)
        {
        }

        public void RedirectXDomainBlocked(object pDisp, ref object StartURL, ref object RedirectURL, ref object Frame, ref object StatusCode)
        {
        }

        public void BeforeScriptExecute(object pDispWindow)
        {
        }

        public void WebWorkerStarted(uint dwUniqueID, string bstrWorkerLabel)
        {
        }

        public void WebWorkerFinsihed(uint dwUniqueID)
        {
        }

        #endregion
    }
}

评论

0赞 John Saunders 3/11/2014
我相信这会奏效的。事实上,它向我表明我正在接收一个事件。它只是没有告诉我为什么。我需要尝试观看网络,但 1) 当我使用 Fiddler 时,整个过程都正常,并且 2) 通信是通过 SSL 进行的。我知道“当我使用 Fiddler 时它有效”通常意味着代理问题,但我的(家庭)网络上没有代理服务器。NavigationError
0赞 noseratio 3/11/2014
@JohnSaunders,您的国际空间站上是否安装了合法的SSL证书?当您在 IE 中拨打相同的 URL 时,完整的 IE 浏览器不会抱怨什么?
0赞 John Saunders 3/11/2014
它不是我的 IIS 服务器。这是一个商业网站。
0赞 noseratio 3/11/2014
@JohnSaunders,如果您愿意进一步尝试,请尝试实现 IHttpSecurity 服务。有一个快捷方式可以通过 IProfferService 执行此操作。
1赞 John Saunders 3/11/2014
我之所以能够猜到这一点,是因为我上了 URL,这应该会导致重定向到我的回调地址。但肯定应该有更明确的迹象吗?我浪费了几个星期的时间,却看不到发生了什么!NavigateError