VB.NET-如何以编程方式将身份验证传递给服务器-如何访问需要身份验证的服务器上的文件

时间:2019-04-01 14:57:12

标签: vb.net authentication server connection

我的目标:

我正在尝试访问我们网络上服务器的C驱动器,目的是搜索某个文件扩展名并返回这些文件的路径。我发现代码here非常有效,但是仅当我在本地计算机上搜索时,或者在已经通过身份验证的服务器的IP中搜索;当我尝试将代码运行到未经身份验证的服务器的IP上时不起作用。

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Cursor = Cursors.WaitCursor
    DirSearch("\\10.0.15.87\c$")
    Cursor = Cursors.Default
End Sub

Public Sub DirSearch(ByVal sDir As String)
    Try
        For Each dir As String In Directory.GetDirectories(sDir)
            For Each file In Directory.GetFiles(dir, "myfile.extension")
                MsgBox(file)
            Next
            DirSearch(dir)
        Next
    Catch ex As Exception
        Debug.WriteLine(ex.Message)
    End Try
End Sub

运行代码时:

我相信代码可以执行完毕;光标将变为WaitCursor约半秒钟,然后返回正常状态,此时不会引发任何错误,并且一切都将照常进行。如果我将“ 10.0.15.87”更改为“ 10.0.15.81”(我已经手动对其进行了身份验证),那么我会弹出一些带有文件路径的MsgBox。 (我确定问题不在搜索文件之内,我知道它适用于其他ip,并且正在搜索的文件位于10.0.15.87的c驱动器中-我相信我只需要通过身份验证即可。 )

当我尝试手动浏览到ip 87时会发生以下情况:

enter image description here

有关10.0.15.87的信息:

  • 它不连接到域,这与我从中运行代码的计算机不同。 (都不是10.0.15.81)
  • 它有一个静态IP
  • 如果我手动尝试访问它,则可以按照上图输入凭据,我只需要通过代码传递凭据即可。

如何在尝试访问服务器之前通过身份验证?

1 个答案:

答案 0 :(得分:0)

我最终找到了一种可以满足我的需求和网络设置的方法,但是一路上,我还找到了另一种更简单并且可能适用于其他人的方法,所以我也将分享它们。

方法1-使用MPR.DLL中的函数

我最终发现this answer是另一个问题。这是对我有用的方法。这看起来就像集成到我的项目中一样:

Imports System.IO    
Imports System.Runtime.InteropServices

Public Class Form1 
    Dim user As String
    Dim pass As String
    Dim path As String

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Cursor = Cursors.WaitCursor
        user = "UsernameString"
        pass = "PasswordString"
        path = "\\10.0.15.87\c$"
        MPRAuth()
        DirSearch(path)
        Cursor = Cursors.Default
    End Sub

    Private Sub MPRAuth()
        Dim nr As New NETRESOURCE
        nr.dwType = RESOURCETYPE_DISK
        nr.lpRemoteName = path
        If WNetAddConnection2(nr, pass, user, 0) <> NO_ERROR Then
            Throw New Exception("WNetAddConnection2 failed.")
        End If
        If WNetCancelConnection2(path, 0, True) <> NO_ERROR Then
            Throw New Exception("WNetCancelConnection2 failed.")
        End If
    End Sub

    Public Sub DirSearch(ByVal sDir As String)
        Try
            For Each dir As String In Directory.GetDirectories(sDir)
                Try
                    For Each file In Directory.GetFiles(dir, "*.exe")
                        MsgBox(file)
                    Next
                Catch ex As Exception
                    Debug.WriteLine(ex.Message)
                End Try
                DirSearch(dir)
            Next
        Catch ex As Exception
            Debug.WriteLine(ex.Message)
        End Try
    End Sub

    <StructLayout(LayoutKind.Sequential)>
    Private Structure NETRESOURCE
        Public dwScope As UInteger
        Public dwType As UInteger
        Public dwDisplayType As UInteger
        Public dwUsage As UInteger
        <MarshalAs(UnmanagedType.LPTStr)>
        Public lpLocalName As String
        <MarshalAs(UnmanagedType.LPTStr)>
        Public lpRemoteName As String
        <MarshalAs(UnmanagedType.LPTStr)>
        Public lpComment As String
        <MarshalAs(UnmanagedType.LPTStr)>
        Public lpProvider As String
    End Structure

    Private Const NO_ERROR As UInteger = 0
    Private Const RESOURCETYPE_DISK As UInteger = 1

    <DllImport("mpr.dll", CharSet:=CharSet.Auto)>
    Private Shared Function WNetAddConnection2(ByRef lpNetResource As NETRESOURCE, <[In](), MarshalAs(UnmanagedType.LPTStr)> ByVal lpPassword As String, <[In](), MarshalAs(UnmanagedType.LPTStr)> ByVal lpUserName As String, ByVal dwFlags As UInteger) As UInteger
    End Function

    <DllImport("mpr.dll", CharSet:=CharSet.Auto)>
    Private Shared Function WNetCancelConnection2(<[In](), MarshalAs(UnmanagedType.LPTStr)> ByVal lpName As String, ByVal dwFlags As UInteger, <MarshalAs(UnmanagedType.Bool)> ByVal fForce As Boolean) As UInteger
    End Function
End Class

方法2-NetworkCredential和CredentialCache

此方法将ip转换为URI并缓存凭据。 我无法使这种方法在与我不同的域中的服务器上使用。

Imports System.Net

Dim builder As New UriBuilder("10.0.15.87")
Dim uri As Uri = builder.Uri
Dim netCred = New NetworkCredential("UsernameString", "PasswordString", "DomainString")
Dim netCache = New CredentialCache()
netCache.Add(uri, "Basic", netCred)
DirSearch("\\10.0.15.87\c$")

方法2的参与程度比方法1少得多,并且只要我尝试连接的服务器与我在同一个域上,它对我来说就可以正常工作。当我尝试连接到不在域中的服务器时,出现错误“用户名或密码不正确”,这是不正确的,因此我不确定问题出在哪里-也许其他人知道。到目前为止,方法1对我来说对于任何服务器都可以正常工作,无论该服务器是域还是在运行代码之前对其进行手动身份验证。希望这对其他人有帮助!