2016-02-22 45 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 –