只有一点点背景知识。我们正在从将散列在数据库中的用户密码存储到直接针对Active Directory进行身份验证。不幸的是,我们有太多内部应用程序,以至于此时无法更新每个应用程序。
因此,我认为我可以只为SQL构建.NET CLR程序集,并修改现有的身份验证存储过程,以针对我们的域控制器(而不是表)验证用户密码,而不是要求所有开发人员更改其代码。
这在我们的初始测试中是成功的,除了由于某种原因(关闭,重新启动,网络等)无法与域控制器通信时。发生这种情况时,我们会超时。我添加了一个try / catch和while循环,以仅跳到下一个域控制器并尝试对其进行身份验证,但是在尝试对下一个服务器进行身份验证之前,它仍然需要20秒钟以上的首次尝试失败。由于这是SQL程序集/函数,并且在存储过程中被调用,所以20秒太长了。
修改我的代码并使对服务器的身份验证尝试失败并在3秒后尝试下一个服务器的最佳方法是什么?以某种方式线程化?
Imports System
Imports System.Data
Imports System.Collections
Imports System.Text
Imports Microsoft.SqlServer.Server
Imports System.Data.SqlTypes
Imports System.Runtime.InteropServices
Imports System.DirectoryServices.AccountManagement
Partial Public Class UserDefinedFunctions
<SqlFunction(Name:="ValidCredentials")>
Public Shared Function ValidCredentials(ByVal Domain As SqlString, ByVal Username As SqlString, ByVal Password As SqlString) As SqlBoolean
'Validates the username and password are correct against the domain.
Dim ServerNum As Integer = 1
Dim Success As Boolean = False
Dim ValidCreds As SqlBoolean = False
'Loop through all 4 domain controllers to attempt authentication against each of them.
While Success = False And ServerNum <= 4
Try
Dim pc As PrincipalContext
If Domain = "employees" Then
pc = New PrincipalContext(ContextType.Domain, "DC-E-0" & ServerNum.ToString & ".employees.ourdomain.loc", "EMPLOYEES\BindAcct", "PASS")
Else
pc = New PrincipalContext(ContextType.Domain, "DC-S-0" & ServerNum.ToString & ".students.ourdomain.loc", "STUDENTS\BindAcct", "PASS")
End If
ValidCreds = pc.ValidateCredentials(Username, Password)
Success = True
Return ValidCreds
Catch ex As Exception
ValidCreds = False
Success = False
ServerNum += 1
End Try
End While
Return ValidCreds
End Function
End Class