我们公司最近开始与合作伙伴开展业务,该合作伙伴正试图为他们的系统提供基于Web的RDP连接。作为其设置文档的一部分,他们要求我们更改工作站的本地网络安全策略:具体而言,更改 发送LM的 LAN Manager身份验证级别设置&安培; NTLM响应 至 仅发送NTLMv2响应 。一旦我进行了此更改并 gpupdate /force
对工作站的更改(然后显示“正确”设置的策略),我可以RDP进入我们的新合作伙伴的服务器就好了,但我的所有连接到PostgreSQL数据库文件的应用程序,出现以下错误:
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
如果我在 发送LM&amp;放置 上设置 LAN Manager身份验证级别,所有这些代码都能正常运行。 NTLM响应 ,但如果我将其更改为 仅发送NTLMv2响应 ,我们的新合作伙伴需要它,它会在{ {1}}陈述。从调试日志中:
PGDB.Open()
奇怪的是,如果我尝试使用SSPI使用PGAdmin III连接,则没有错误。我重新启动了服务器上的PostgreSQL服务(以防万一),但仍然遇到了同样的错误。我甚至开始重新启动整个服务器,但错误仍然存在。
现在,如果我将本地网络安全策略设置更改回 发送LM&amp; NTLM响应 ,应用程序正常运行,但我们无法建立与合作伙伴系统的RDP连接。我甚至尝试将策略设置更改为 发送LM&amp; NTLM - 如果协商 ,则使用NTLMv2会话安全性。同样,我的应用程序将连接到数据库而没有错误,但RDP连接失败。
我想问题归结为:有人知道如何让Npgsql连接到PostgreSQL数据库,而本地网络安全策略的 LAN Manager身份验证级别设置配置为 < em>仅发送NTLMv2响应 ?由于其他一切似乎都能正常工作(据我所知),这似乎是失败的原因。
编辑:由于我在Visual Studio 2015中工作,我尝试通过NuGet控制台更新我正在使用的Npgsql版本。这将库更新到版本3.0.5.0,我在 仅发送NTLMv2响应 设置下再次测试了连接。这次应用程序的连接似乎正常工作。为了确定,我删除了3.0.5.0参考并添加了我的旧版本(显然我在2.0.11.92 - 是的,是的...我知道)并再次测试,这给了我和以前一样的错误。
看起来导致问题的原因已经解决了以后对Npgsql库的更新。当然,这意味着,除非我正在使用的版本(2.0.11.92)有解决方法,否则我将不得不更新所有内部应用程序以使用更新的库。我真的现在没有时间做所有这些,所以如果有人有办法让这项工作,我很乐意听到它。
答案 0 :(得分:1)
@G_Hosa_Phat。 我记得我们对ntlm支持进行了大量修改,因为您可以通过测试最近的3.0.x版本来检查并使其正常工作......
没有配置选项可以更改您可以使用的ntlm身份验证的行为。 我想你真的需要更新你的库。
但我建议您更新到最新的2.x版本,而不是3.0.x,因为3.0.x的更改超出了ntlm的支持,它可能会破坏您现有的系统。
很抱歉给你这个坏消息。 :(
我希望它有所帮助。