我们公司最近开始与合作伙伴开展业务,该合作伙伴试图为我们的系统提供基于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 –