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.
If you know User ID/Password of Windows user, used in Integrated security login, you can try following approach.
First declare calls to Windows API functions:
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
Then declare 2 helper functions
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
With this preparation made you can make calls like this:
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)
This code is kind of raw, but it works. You will need to add appropriate error handling etc. to make it a production code. Pass user ID in format "user@domain" in "i_sUserID" parameter and user's password in "i_sPassword" parameter.