2016-02-22 72 views
0

我們公司最近開始與合作伙伴開展業務,該合作伙伴試圖爲我們的系統提供基於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)有解決方法,否則我將不得不更新所有內部應用程序以使用更新的庫。我真的沒有時間對所有的,現在,所以如果有人有辦法,使這項工作,我很樂意聽到它。

回答

1

@G_Hosa_Phat。 我記得我們對ntlm支持做了大量的修改,你可以通過測試最新的3.0.x版本來檢查它,並讓它工作...

沒有配置選項來改變你可以使用的ntlm認證行爲。 我認爲你真的需要更新你的圖書館。

但我會建議您更新,而不是作爲3.0.x的3.0.x中的變化,以最近的2.x版,都超越了NTLM支持,它可以打破現有的系統。

對不起,給你這個壞消息。 :(

我希望它能幫助。

+0

謝謝你的信息。除非我們的新夥伴可以給我一個備用路由到他們的系統,我想是時候開始更新和測試我的內部應用程序。這裏只有約50時間......哦,好吧 –

+0

** @ 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 –