Visual Basic 以编程方式将用户名和密码传递给 https url 以使 webbrowser 显示网页并从网页下载
Posted
技术标签:
【中文标题】Visual Basic 以编程方式将用户名和密码传递给 https url 以使 webbrowser 显示网页并从网页下载【英文标题】:Visual basic programmatically pass username and password to https url to make webbrowser display webpage and also download from webpage 【发布时间】:2017-08-30 19:07:02 【问题描述】:使用普通 HTTP,我可以下载上传并导航到路由器,但当路由器使用 HTTPS 时,我找不到任何代码来执行这些操作。
要下载我用这个:
Try
My.Computer.Network.DownloadFile("http://" & "180.29.74.70" & "/cgi-bin/log.cgi", "C:\Users\ssb\Desktop\randomword.txt", "username", "password")
WebBrowser1.Refresh()
Catch ex As Exception
MessageBox.Show("Router not sufficient for operation Return for Inspection cannot download log file")
End Try
要上传文件,我使用这个:
My.Computer.Network.UploadFile("C:\Users\ssb\Desktop\tomtn.txt", "http://" & "180.29.74.70" & "/cgi-bin/updateconfig.cgi", "username", "password")
要导航到 HTTP 上的网页,我使用以下命令:
WebBrowser1.Navigate("https://username:password@180.29.74.70 ")
但是当我使用 HTTPS 时:
WebBrowser1.Navigate("https://username:password@180.29.74.70 ")
我收到此安全警报:
然后我点击“是”并进入该页面——但我需要代码来绕过此类安全问题。
【问题讨论】:
为什么在代码中 http 前面有两个星号,后面有两个星号? ex 的内容是什么(您捕获的异常)? WebBrowser1和下载有什么关系(和My.Computer.Network不一样)? @z32a7ul——我猜这是与 SO markdown 语法有关的错误。 是的,但是如果证书不受信任,这使得它更像是 https 而不仅仅是 http,我不认为你应该能够以编程方式绕过安全措施,但事实证明你可以。同样,当使用更安全的用户名或密码(如 p@ssword)或使用您的电子邮件时,例如 something@somewere.com 将它们与标题一起传递以导航到网页时,应编码特殊字符而不是 @ 您应该使用 %40 例如p%40wword 如果您要使用 My.Computer.Network.DownloadFile 下载,则正常密码应该可以使用 【参考方案1】:尽管它们之间的关系松散,但您在这里提出了两个单独的问题。
-
为什么我使用
WebBrowser
控件通过HTTPS加载页面时调用失败?
为什么我使用DownloadFile()
方法通过HTTPS下载文件时调用失败?
首先,您需要消除代码失败的可能性。使用已知可以正常工作的公共 HTTPS URL 尝试上述两个任务。
如果您发现问题的根源在于您的私有 URL,您可能需要考虑是否要忽略 WebBrowser
控件中的 SSL 错误。
您可以使用this blog post 中的(未经测试,已翻译为 VB)代码:
Partial Public Class Form1
Inherits Form
Private WithEvents WebBrowser As New WebBrowser
Private Sub WebBrowser_DocumentCompleted(Sender As Object, e As WebBrowserDocumentCompletedEventArgs) Handles WebBrowser.DocumentCompleted
If e.Url.ToString() = "about:blank" Then
'create a certificate mismatch
WebBrowser.Navigate("https://74.125.225.229/")
End If
End Sub
End Class
<Guid("6D5140C1-7436-11CE-8034-00AA006009FA")>
<InterfaceType(ComInterfaceType.InterfaceIsIUnknown)>
<ComImport>
Public Interface UCOMIServiceProvider
<PreserveSig>
Function QueryService(<[In]> ByRef guidService As Guid, <[In]> ByRef riid As Guid, <Out> ByRef ppvObject As IntPtr) As <MarshalAs(UnmanagedType.I4)> Integer
End Interface
<ComImport>
<ComVisible(True)>
<Guid("79eac9d5-bafa-11ce-8c82-00aa004ba90b")>
<InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)>
Public Interface IWindowForBindingUI
<PreserveSig>
Function GetWindow(<[In]> ByRef rguidReason As Guid, <[In], Out> ByRef phwnd As IntPtr) As <MarshalAs(UnmanagedType.I4)> Integer
End Interface
<ComImport>
<ComVisible(True)>
<Guid("79eac9d7-bafa-11ce-8c82-00aa004ba90b")>
<InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)>
Public Interface IHttpSecurity
'derived from IWindowForBindingUI
<PreserveSig>
Function GetWindow(<[In]> ByRef rguidReason As Guid, <[In], Out> ByRef phwnd As IntPtr) As <MarshalAs(UnmanagedType.I4)> Integer
<PreserveSig>
Function OnSecurityProblem(<[In], MarshalAs(UnmanagedType.U4)> dwProblem As UInteger) As Integer
End Interface
Public Class MyWebBrowser
Inherits WebBrowser
Public Shared IID_IHttpSecurity As New Guid("79eac9d7-bafa-11ce-8c82-00aa004ba90b")
Public Shared IID_IWindowForBindingUI As New Guid("79eac9d5-bafa-11ce-8c82-00aa004ba90b")
Public Const S_OK As Integer = 0
Public Const S_FALSE As Integer = 1
Public Const E_NOINTERFACE As Integer = &H80004002
Public Const RPC_E_RETRY As Integer = &H80010109
Protected Overrides Function CreateWebBrowserSiteBase() As WebBrowserSiteBase
Return New MyWebBrowserSite(Me)
End Function
Private Class MyWebBrowserSite
Inherits WebBrowserSite
Implements UCOMIServiceProvider
Implements IHttpSecurity
Implements IWindowForBindingUI
Private myWebBrowser As MyWebBrowser
Public Sub New(myWebBrowser As MyWebBrowser)
MyBase.New(myWebBrowser)
Me.myWebBrowser = myWebBrowser
End Sub
Public Function QueryService(ByRef guidService As Guid, ByRef riid As Guid, ByRef ppvObject As IntPtr) As Integer Implements UCOMIServiceProvider.QueryService
If riid = IID_IHttpSecurity Then
ppvObject = Marshal.GetComInterfaceForObject(Me, GetType(IHttpSecurity))
Return S_OK
End If
If riid = IID_IWindowForBindingUI Then
ppvObject = Marshal.GetComInterfaceForObject(Me, GetType(IWindowForBindingUI))
Return S_OK
End If
ppvObject = IntPtr.Zero
Return E_NOINTERFACE
End Function
Public Function GetWindow(ByRef rguidReason As Guid, ByRef phwnd As IntPtr) As Integer Implements IHttpSecurity.GetWindow, IWindowForBindingUI.GetWindow
If rguidReason = IID_IHttpSecurity OrElse rguidReason = IID_IWindowForBindingUI Then
phwnd = myWebBrowser.Handle
Return S_OK
Else
phwnd = IntPtr.Zero
Return S_FALSE
End If
End Function
Public Function OnSecurityProblem(dwProblem As UInteger) As Integer Implements IHttpSecurity.OnSecurityProblem
'ignore errors
'undocumented return code, does not work on IE6
Return S_OK
End Function
End Class
End Class
关于问题 #2:看来您可能混淆了WebBrowser
和DownloadFile()
。您可能已经发现,WebBrowser
控件不下载文件。但是,您可以使用this technique 模拟行为:
Partial Public Class Form2
Inherits Form
Private Sub WebBrowser_Navigating(Sender As Object, e As WebBrowserNavigatingEventArgs) Handles WebBrowser.Navigating
Dim sFilePath As String
Dim oClient As Net.WebClient
' This can be any conditional criteria you wish '
If (e.Url.Segments(e.Url.Segments.Length - 1).EndsWith(".pdf")) Then
SaveFileDialog.FileName = e.Url.Segments(e.Url.Segments.Length - 1)
e.Cancel = True
If SaveFileDialog.ShowDialog() = DialogResult.OK Then
sFilePath = SaveFileDialog.FileName
oClient = New Net.WebClient
AddHandler oClient.DownloadFileCompleted, New AsyncCompletedEventHandler(AddressOf DownloadFileCompleted)
oClient.DownloadFileAsync(e.Url, sFilePath)
End If
End If
End Sub
Private Sub DownloadFileCompleted(Sender As Object, e As AsyncCompletedEventArgs)
MessageBox.Show("File downloaded")
End Sub
Private WithEvents SaveFileDialog As New SaveFileDialog
Private WithEvents WebBrowser As New WebBrowser
End Class
无论如何,解决此问题的第一步是确定是您的代码还是私有 URL 导致了您的问题。
【讨论】:
@Nikki — 解决 IE 标记的安全问题可能会更好(WebBrowser
控件使用 IE)。毕竟,安全应该是第一位的;绕过安全措施的变通办法应该是您最后的手段。对于第一个错误,您有两个选择:1] 在您的证书存储中安装根 CA 或 2] 为 IIS 中的服务器证书切换到受信任的 CA(请参阅Let's Encrypt 以获得免费的域验证证书)。对于第二个错误,修改您的 URL 以使用证书中指示的主机名而不是 IP 地址。
每个路由器都有一个不同的 ipaddress 都在同一范围内有数百个路由器需要到达主要目标是让应用程序登录到路由器下载其配置并检查它们是否正确应用程序必须尽可能简单,因为要进行测试的人可能什么都不知道,我会对证书进行一些研究,但我所有的代码都可以在 http 上运行,如果我能通过安全检查,我基本上就完成了
@Nikki——我明白了。然后,您似乎无法使用上面的代码绕过安全检查(假设它有效 - 再次,我没有测试它)。您在集成它时遇到什么问题?您应该能够将代码保存到项目中的新 *.vb 文件中。将 Form1
和 Form2
类重命名为与现有表单类相同。【参考方案2】:
这里需要做的主要事情是以编程方式从 https url 下载文件,同时使用被安全证书问题阻止的用户名和密码
搜索2周后的解决方案是
要下载文件,您可以使用以下代码暂时禁用安全证书请求,然后在代码运行后再次启用安全证书
您甚至不需要浏览器的第一个代码,它会自动将文件保存到您的桌面
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'check if a simular file doesnt exists so you can create a new file and deletes the file if it exists
If File.Exists("C:\pathtoyourfile\yourfilename.txt") Then
File.Delete("C:\pathtoyourfile\yourfilename.txt")
End If
'Type this before your download or hhtps request
'ByPass SSL Certificate Validation Checking
System.Net.ServicePointManager.ServerCertificateValidationCallback =
Function(se As Object,
cert As System.Security.Cryptography.X509Certificates.X509Certificate,
chain As System.Security.Cryptography.X509Certificates.X509Chain,
sslerror As System.Net.Security.SslPolicyErrors) True
'Call web application/web service with HTTPS URL here
'=========================================================================================
'ServicePointManager.ServerCertificateValidationCallback = AddressOf AcceptAllCertifications
Try
My.Computer.Network.DownloadFile("https://176.53.78.22/filenameonserveryouwanttodownload", "C:\pathtoyourfile\yourfilename.txt", "Yourusername", "yourpassword")
WebBrowser1.Refresh()
Catch ex As Exception
MessageBox.Show("message saying something didnt work")
'exit sub if it worked
Exit Sub
End Try
MessageBox.Show(" message saying it worked")
'=========================================================================================
'Restore SSL Certificate Validation Checking
System.Net.ServicePointManager.ServerCertificateValidationCallback = Nothing
End Sub
然后浏览到一个网址会弹出以下代码并弹出安全弹出窗口但只需选择是浏览网页正常工作
WebBrowser1.Navigate("https://username:password@180.29.74.70 ")
【讨论】:
从您在主帖上的图片来看,您的 ssl 证书似乎有两个问题。 1. 您从不受 Windows 信任的提供商处获得证书。 2.您正在通过IP地址访问主机。 ***.com/questions/2043617/…【参考方案3】:如你所说:
[...] 我需要代码来绕过此类安全问题。
换句话说,您需要“自动接受自签名 SSL 证书”,所以我认为这是一个重复的问题:VB .net Accept Self-Signed SSL certificate,这可能符合您的需求。
尤其是slaks 答案:
在VB.Net中,你需要写:
ServicePointManager.ServerCertificateValidationCallback = AddressOf AcceptAllCertifications
【讨论】:
以上是关于Visual Basic 以编程方式将用户名和密码传递给 https url 以使 webbrowser 显示网页并从网页下载的主要内容,如果未能解决你的问题,请参考以下文章