2

Although I found many posts with this same error, I couldn't find if my error is fixable or not.

There is a database which I have read permission with my window login on the network. I just use SSMS to access the table but that isn't really have the best interface in the world so I wrote a small website that can connect to the table and filter the data I want and display them nicely.

I use Integrated Security = SSPI (also tried TRUE) and it all works fine until this point. I run the website using VS2010. But running a website using VS2010 isn't really ideal thing to do so I put my website on IIS 7 on my machine (i.e. Localhost:xxx). And this's when I got the above error.

All those issues can be fixed if I can just get a user in the database with only a read permission to the table I want to read but that isn't simply possible in my case. There is nothing i can change with the database.

So is there any work around to host the website on local IIS with a connection string that uses integrated security and connects to a remote database with window login credential?

Thanks.

4

1 回答 1

1

如果您知道集成安全登录中使用的 Windows 用户的用户 ID/密码,您可以尝试以下方法。

首先声明对 Windows API 函数的调用:

Private Enum LogonSessionType As Integer
  Interactive = 2
  Network
  Batch
  Service
  NetworkCleartext = 8
  NewCredentials
End Enum

Private Enum LogonProvider As Integer
  WinDefault = 0
  WinNT35
  WinNT40
  WinNT50
End Enum

<DllImport("advapi32.dll", SetLastError:=True)> _
Private Shared Function LogonUser(ByVal userID As String, _
                                  ByVal domain As String, _
                                  ByVal password As String, _
                                  ByVal logonType As LogonSessionType, _
                                  ByVal LogonProv As LogonProvider, _
                                  ByRef token As IntPtr) As Boolean
End Function

<DllImport("kernel32.dll", SetLastError:=True)> _
Private Shared Function CloseHandle(ByVal handle As IntPtr) As Boolean

End Function

然后声明2个辅助函数

Sub BeginImpersonate(ByVal i_sUserID As String, ByVal i_sPassword As String, ByRef o_impersonatedUser As WindowsImpersonationContext, ByRef o_token As IntPtr)

    o_token = IntPtr.Zero
    o_impersonatedUser = Nothing

    Dim bLoginSuccessful As Boolean = LogonUser(i_sUserID, Nothing, i_sPassword, LogonSessionType.Interactive, LogonProvider.WinDefault, o_token)

    If bLoginSuccessful Then
         Dim id As New WindowsIdentity(o_token)
         o_impersonatedUser = id.Impersonate()
    Else
         Throw New Exception ("Logon failed: Error " & Marshal.GetLastWin32Error.ToString)
    End If

End Sub


Sub EndImpersonate(ByVal i_impersonatedUser As WindowsImpersonationContext, ByVal i_token As IntPtr)
    If i_impersonatedUser IsNot Nothing Then i_impersonatedUser.Undo()
    If i_token <> IntPtr.Zero Then CloseHandle(i_token)
End Sub

做好这些准备后,您可以像这样拨打电话:

Dim impersonatedUser As WindowsImpersonationContext = Nothing
Dim token As IntPtr = IntPtr.Zero

BeginImpersonate(i_sUserID, i_sPassword, impersonatedUser, token)

'Do your DB stufff here, open connection etc.

EndImpersonate(impersonatedUser, token)

这段代码有点原始,但它有效。您将需要添加适当的错误处理等以使其成为生产代码。在“i_sUserID”参数中以“user@domain”格式传递用户 ID,在“i_sPassword”参数中传递用户密码。

于 2013-06-10T15:48:36.430 回答