我們公司最近開始與合作伙伴開展業務,該合作伙伴試圖爲我們的系統提供基於Web的RDP連接。由於其設置文檔的一部分,他們需要我們改變本地網絡安全策略爲我們的工作站:具體而言,從以前發送LM & NTLM響應改變LAN Manager身份驗證級別設置到發送NTLMv2只回應。一旦我做了這個改變,並且工作站的變化(然後顯示策略「正確」設置),我可以將RDP加入到我們的新合作伙伴的服務器中,但是我的所有連接到PostgreSQL數據庫文件的應用程序都與以下錯誤:更改Windows本地網絡安全策略後出現Npgsql錯誤
FATAL: XX000: could not accept SSPI security context
我已經建立了一個臨時的小應用程序來測試用下面的代碼在Visual Studio中連接(網絡信息刪節):
Imports Npgsql
Imports System.DirectoryServices
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim PGUserName As String
Dim PGDB As NpgsqlConnection = Nothing
Dim PGConnection As NpgsqlConnectionStringBuilder
Dim PGCommand As NpgsqlCommand = Nothing
Dim PGAdapter As NpgsqlDataAdapter = Nothing
Dim TestSQL As String = String.Empty
Dim TestData As New DataTable
PGUserName = GetActiveDirectoryUsername()
TestSQL = "SELECT * FROM testdb"
PGConnection = New NpgsqlConnectionStringBuilder
With PGConnection
NpgsqlEventLog.Level = LogLevel.Debug
NpgsqlEventLog.LogName = "C:\TEST\NPGSQLEVENTLOG.TXT"
.Host = "<PGSQLSERVER>"
.Port = <PORT>
.UserName = PGUserName
.IntegratedSecurity = True
.Database = "testing"
End With
PGDB = New NpgsqlConnection(PGConnection.ConnectionString)
Try
PGDB.Open()
PGCommand = New NpgsqlCommand(TestSQL, PGDB)
PGAdapter = New NpgsqlDataAdapter(PGCommand)
PGAdapter.Fill(TestData)
Catch ex As Exception
MessageBox.Show(ex.Message)
Finally
If Not PGAdapter Is Nothing Then
PGAdapter.Dispose()
End If
If Not PGCommand Is Nothing Then
PGCommand.Dispose()
End If
If PGDB.State <> ConnectionState.Closed Then
PGDB.Close()
End If
If Not PGDB Is Nothing Then
PGDB.Dispose()
End If
If Not TestData Is Nothing Then
TestData.Dispose()
End If
End Try
End Sub
Friend Function GetDirectoryEntry() As DirectoryEntry
Dim dirEntry As DirectoryEntry = New DirectoryEntry()
dirEntry.Path = "LDAP://<ADSERVERIP>/DC=<DOMAIN>"
Return dirEntry
End Function
Friend Function GetActiveDirectoryUsername() As String
Try
Dim MyDirectory As DirectoryEntry = GetDirectoryEntry()
Dim search As New DirectorySearcher(MyDirectory)
search.Filter = String.Format("(&(SAMAccountName={0}))", Environment.UserName)
'Use the .FindOne() Method to stop as soon as a match is found
Dim result As SearchResult = search.FindOne()
If result Is Nothing Then
Return ""
Else
Return result.Properties("samaccountname").Item(0).ToString
End If
Catch ex As Exception
MessageBox.Show(ex.Message, "Active Directory Error", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1)
Return ""
End Try
End Function
End Class
所有這些代碼的工作完全如果我離開了LAN M anager認證級別集上發送LM & NTLM響應,但如果我將它更改爲僅發送NTLMv2響應如我們新的合作伙伴需要,它拋出的PGDB.Open()
聲明例外。從調試日誌:
2/22/16 12:32:58 PM 11452 Debug Entering NpgsqlConnection.NpgsqlConnection(NpgsqlConnection())
2/22/16 12:32:58 PM 11452 Debug ConnectionString Option: HOST = <PGSQLSERVER>
2/22/16 12:32:58 PM 11452 Debug ConnectionString Option: PORT = <PORT>
2/22/16 12:32:58 PM 11452 Debug ConnectionString Option: PROTOCOL = 3
2/22/16 12:32:58 PM 11452 Debug ConnectionString Option: DATABASE = testing
2/22/16 12:32:58 PM 11452 Debug ConnectionString Option: USER ID = <PGSQLUSERNAME>
2/22/16 12:32:58 PM 11452 Debug ConnectionString Option: SSL = False
2/22/16 12:32:58 PM 11452 Debug ConnectionString Option: SSLMODE = Disable
2/22/16 12:32:58 PM 11452 Debug ConnectionString Option: TIMEOUT = 15
2/22/16 12:32:58 PM 11452 Debug ConnectionString Option: POOLING = True
2/22/16 12:32:58 PM 11452 Debug ConnectionString Option: CONNECTIONLIFETIME = 15
2/22/16 12:32:58 PM 11452 Debug ConnectionString Option: MINPOOLSIZE = 1
2/22/16 12:32:58 PM 11452 Debug ConnectionString Option: MAXPOOLSIZE = 20
2/22/16 12:32:58 PM 11452 Debug ConnectionString Option: SYNCNOTIFICATION = False
2/22/16 12:32:58 PM 11452 Debug ConnectionString Option: COMMANDTIMEOUT = 20
2/22/16 12:32:58 PM 11452 Debug ConnectionString Option: ENLIST = False
2/22/16 12:32:58 PM 11452 Debug ConnectionString Option: PRELOADREADER = False
2/22/16 12:32:58 PM 11452 Debug ConnectionString Option: USEEXTENDEDTYPES = False
2/22/16 12:32:58 PM 11452 Debug ConnectionString Option: INTEGRATED SECURITY = True
2/22/16 12:32:58 PM 11452 Debug ConnectionString Option: COMPATIBLE = 2.0.11.92
2/22/16 12:32:58 PM 11452 Debug Entering NpgsqlConnection.Open()
2/22/16 12:32:58 PM 11452 Debug Get NpgsqlClosedState.Instance
2/22/16 12:32:58 PM 11452 Debug Get NpgsqlClosedState.Instance
2/22/16 12:32:58 PM 11452 Debug Entering NpgsqlClosedState.Open()
2/22/16 12:32:58 PM 11452 Debug Attempt to connect to '<PGSQLSERVERIP>'.
2/22/16 12:32:58 PM 11452 Normal Connected to: <PGSQLSERVER>:<PORT>.
2/22/16 12:32:58 PM 11452 Debug Entering NpgsqlStartupPacket.NpgsqlStartupPacket()
2/22/16 12:32:58 PM 11452 Debug Entering NpgsqlStartupPacket.WriteToStream()
2/22/16 12:32:58 PM 11452 Debug Entering NpgsqlStartupPacket.WriteToStream_Ver_3()
2/22/16 12:32:58 PM 11452 Debug Entering PGUtil.WriteString()
2/22/16 12:32:58 PM 11452 Debug String written: user.
2/22/16 12:32:58 PM 11452 Debug Entering PGUtil.WriteString()
2/22/16 12:32:58 PM 11452 Debug String written: <PGSQLUSERNAME>.
2/22/16 12:32:58 PM 11452 Debug Entering PGUtil.WriteString()
2/22/16 12:32:58 PM 11452 Debug String written: database.
2/22/16 12:32:58 PM 11452 Debug Entering PGUtil.WriteString()
2/22/16 12:32:58 PM 11452 Debug String written: testing.
2/22/16 12:32:58 PM 11452 Debug Entering PGUtil.WriteString()
2/22/16 12:32:58 PM 11452 Debug String written: DateStyle.
2/22/16 12:32:58 PM 11452 Debug Entering PGUtil.WriteString()
2/22/16 12:32:58 PM 11452 Debug String written: ISO.
2/22/16 12:32:58 PM 11452 Debug Entering NpgsqlState.ProcessBackendResponses()
2/22/16 12:32:58 PM 11452 Debug AuthenticationRequest message received from server.
2/22/16 12:32:58 PM 11452 Debug Entering NpgsqlStartupState.Authenticate()
2/22/16 12:32:58 PM 11452 Debug Entering NpgsqlPasswordPacket.NpgsqlPasswordPacket()
2/22/16 12:32:58 PM 11452 Debug Entering NpgsqlPasswordPacket.WriteToStream()
2/22/16 12:32:58 PM 11452 Debug Entering PGUtil.WriteBytes()
2/22/16 12:32:58 PM 11452 Debug Unable to find resource string Log_BytesWritten for class PGUtil
2/22/16 12:32:58 PM 11452 Debug AuthenticationRequest message received from server.
2/22/16 12:32:58 PM 11452 Debug Entering NpgsqlStartupState.Authenticate()
2/22/16 12:32:58 PM 11452 Debug Entering NpgsqlPasswordPacket.NpgsqlPasswordPacket()
2/22/16 12:32:58 PM 11452 Debug Entering NpgsqlPasswordPacket.WriteToStream()
2/22/16 12:32:58 PM 11452 Debug Entering PGUtil.WriteBytes()
2/22/16 12:32:58 PM 11452 Debug Unable to find resource string Log_BytesWritten for class PGUtil
2/22/16 12:32:58 PM 11452 Debug Entering PGUtil.ReadString()
2/22/16 12:32:58 PM 11452 Debug Get NpgsqlEventLog.LogLevel
2/22/16 12:32:58 PM 11452 Debug String read: FATAL.
2/22/16 12:32:58 PM 11452 Debug Entering PGUtil.ReadString()
2/22/16 12:32:58 PM 11452 Debug Get NpgsqlEventLog.LogLevel
2/22/16 12:32:58 PM 11452 Debug String read: XX000.
2/22/16 12:32:58 PM 11452 Debug Entering PGUtil.ReadString()
2/22/16 12:32:58 PM 11452 Debug Get NpgsqlEventLog.LogLevel
2/22/16 12:32:58 PM 11452 Debug String read: could not accept SSPI security context.
2/22/16 12:32:58 PM 11452 Debug Entering PGUtil.ReadString()
2/22/16 12:32:58 PM 11452 Debug Get NpgsqlEventLog.LogLevel
2/22/16 12:32:58 PM 11452 Debug String read: The token supplied to the function is invalid
(80090308).
2/22/16 12:32:58 PM 11452 Debug Entering PGUtil.ReadString()
2/22/16 12:32:58 PM 11452 Debug Get NpgsqlEventLog.LogLevel
2/22/16 12:32:58 PM 11452 Debug String read: src\backend\libpq\auth.c.
2/22/16 12:32:58 PM 11452 Debug Entering PGUtil.ReadString()
2/22/16 12:32:58 PM 11452 Debug Get NpgsqlEventLog.LogLevel
2/22/16 12:32:58 PM 11452 Debug String read: 1024.
2/22/16 12:32:58 PM 11452 Debug Entering PGUtil.ReadString()
2/22/16 12:32:58 PM 11452 Debug Get NpgsqlEventLog.LogLevel
2/22/16 12:32:58 PM 11452 Debug String read: pg_SSPI_error.
2/22/16 12:32:58 PM 11452 Debug ErrorResponse message from Server: could not accept SSPI security context.
2/22/16 12:32:58 PM 11452 Normal An NpgsqlException occured: FATAL: XX000: could not accept SSPI security context.
2/22/16 12:33:02 PM 11452 Debug Entering NpgsqlConnection.Dispose()
2/22/16 12:33:03 PM 11452 Debug Entering NpgsqlConnection.Close()
奇怪的是,如果我嘗試使用的pgAdmin III使用SSPI連接,沒有錯誤。我重新啓動了服務器上的PostgreSQL服務(以防萬一),並且仍然有相同的錯誤。我甚至去重新啓動整個服務器,但錯誤仍然存在。
現在,如果我改變了本地網絡安全策略設置回發送LM & NTLM響應,應用程序工作正常,但我們不能建立RDP連接到我們合作伙伴的系統。我甚至嘗試將策略設置更改爲發送LM & NTLM - 如果協商使用NTLMv2會話安全性。再一次,我的應用程序將連接到數據庫而沒有錯誤,但RDP連接失敗。
我想這個問題歸結爲:有誰知道如何獲得Npgsql的連接到PostgreSQL數據庫,而本地網絡安全策略的LAN Manager身份驗證級別設置配置爲僅發送 NTLMv2響應?由於一切似乎正常工作(據我所知),這似乎是失敗的關鍵。
編輯:由於我在Visual Studio 2015中工作,我嘗試更新我通過NuGet控制檯使用的Npgsql版本。這更新了庫到版本3.0.5.0,並且我再次測試了連接發送NTLMv2響應只有設置。這次應用程序的連接似乎正常工作。只是可以肯定,我刪除了3.0.5.0參考,並加入我的舊版本的背(顯然我在2.0.11.92 - 嗯,嗯......我知道),並再次進行測試,這給了我同樣的錯誤之前。
它看起來像什麼原因造成的問題已得到解決後更新到圖書館Npgsql的。當然,這意味着,除非我使用的版本(2.0.11.92)有解決方法,否則我將不得不更新所有內部應用程序以使用更新的庫。我真的沒有時間對所有的,現在,所以如果有人有辦法,使這項工作,我很樂意聽到它。
謝謝你的信息。除非我們的新夥伴可以給我一個備用路由到他們的系統,我想是時候開始更新和測試我的內部應用程序。這裏只有約50時間......哦,好吧 –
** @ FranciscoJunior **我發現2.2.7版本(最新的2.x版本可在NuGet網站上找到[https://www.nuget.org/我的許多應用程序都是在VS2008中構建的,其中.NET框架的最高版本爲3.5,當我嘗試向這些版本添加3.0.5版本時,它可以' t找到必要的引用,這意味着我可以在新的VS2015下重建所有的東西以利用最新的Npgsql版本,或者我可以使用2.2.7版本「回退並投」版。猜猜我現在選擇哪一個。 :-P –