一般來說IIS的驗證方式有好幾種,比較常見的就是匿名驗證,整合Windows驗證等等。 但是整合Windows驗證每次都會談個對話方塊出來,很麻煩,特別是在使用代理的情況下。
於是想能不能用一種Form的方式實現Windows驗證呢? 當然啦,想想而已,本來對WEB開發就不算熟, Windows方面的就更差了。
在網上搜尋到了一種方式,利用 advapi32.dll的LogonUser方法是可以驗證你輸入的使用者名稱密碼是不是Windows的有效使用者的。
代碼如下 :
'include permissions namespace for security attributes
'include principal namespace for windowsidentity class
'include interopservices namespace for dllImports.
Imports System.Security.Principal
Imports System.Security.Permissions
Imports System.Runtime.InteropServices
'<Assembly: SecurityPermissionAttribute(SecurityAction.RequestMinimum, UnmanagedCode:=True)>
Public Class LogInUser
<DllImport("C://WINDOWS//System32//advapi32.dll")> _
Private Shared Function LogonUser(ByVal lpszUsername As String, ByVal lpszDomain As String, ByVal
lpszPassword As String, _ ByVal dwLogonType As Integer, ByVal dwLogonProvider As Integer, ByRef phToken As Integer) As Boolean
End Function
<DllImport("C://WINDOWS//System32//Kernel32.dll")> _
Private Shared Function GetLastError() As Integer
End Function
Public Shared Function LogInThisUser(ByVal username As String, ByVal domainname As String, _
ByVal password As String) As String
Try
'The Windows NT user token.
Dim token1 As Integer
'Get the user token for the specified user, machine, and password using the unmanaged LogonUser method.
'The parameters for LogonUser are the user name, computer name, password,
'Logon type (LOGON32_LOGON_NETWORK_CLEARTEXT), Logon provider (LOGON32_PROVIDER_DEFAULT),
'and user token.
Dim loggedOn As Boolean = LogonUser(username, domainname, password, 3, 0, token1)
'impersonate user
Dim token2 As IntPtr = New IntPtr(token1)
Dim mWIC As WindowsImpersonationContext = _
New WindowsIdentity(token2).Impersonate
Catch e As Exception
'error occurred.. error number unknown.
Return "Err. occurred : " & e.Message
End Try
Dim winUser As WindowsIdentity
Return winUser.GetCurrent.Name
End Function
End Class
不過網上的VB代碼,我習慣用的是C#,於是一行一行的轉換。結果後來執行的時候就出錯了: 提示 嘗試讀取或寫入受保護的記憶體。這通常指示其他記憶體已損壞。
開始以為是因為要擷取系統使用者資訊,所以需要的許可權比較高或者是會讀去受保護的系統資訊。 繼續搜尋這個錯誤,發現是因為使用了Unmanaged 程式碼,而且我轉換LogonUser函數中的最後一個變數 ByRef phToken As Integer時,轉換成了INT,實際上應該是ref InPtr類型,因為引用Unmanaged 程式碼函數參數錯誤,所以報這個錯誤。
至於Managed 程式碼和Unmanaged 程式碼更詳細的差別還得以後慢慢研究了。。