gpt4 book ai didi

c# - 将 System.DirectoryServices.AccountManagement.PrincipalContext.ValidateCredentials 与 SAM 一起使用时出现奇怪错误

转载 作者:行者123 更新时间:2023-11-30 12:19:04 24 4
gpt4 key购买 nike

我正在使用 IIS 6.0 托管 WCF Web 服务。我的应用程序池在本地管理员帐户下运行,并且我定义了其他本地用户来访问 Web 服务。我编写了以下代码来验证用户:


//Any public static (Shared in Visual Basic) members of this type are thread safe
public static PrincipalContext vpc;

//static initializer
static UserManagement()
{
vpc = new PrincipalContext(ContextType.Machine);
}

//Determines whether the given credentials are for a valid Administrator
public static bool validateAdminCredentials(string username, string password)
{
using (PrincipalContext principalContext = new PrincipalContext(ContextType.Machine))
{
if (vpc.ValidateCredentials(username, password))
{
using (UserPrincipal user = UserPrincipal.FindByIdentity(principalContext, IdentityType.SamAccountName, username))
{
foreach (GroupPrincipal gp in user.GetGroups())
{
try
{
if (gp.Name.Equals("Administrators"))
{
return true;
}
}
finally
{
gp.Dispose();
}
}
}
}

return false;
} //end using PrincipalContext
}

...在另一个类中:


//verify the user's password
if (!UserManagement.vpc.ValidateCredentials(username, password))
{
string errorMsg = string.Format("Invalid credentials received for user '{0}'", username);
throw new Exception(errorMsg);
}

(注意:我使用 public static PrincipalContext (vpc) 仅用于调用 ValidateCredentials 方法;我创建了一个不同的临时 PrincipalContext 来创建、删除和查找用户和组,因为我在我尝试对所有内容使用全局 PrincipalContext)。

因此,在大多数情况下,这段代码都能很好地工作。但是,间歇性地出现以下错误:

不允许同一用户使用多个用户名多次连接到服务器或共享资源。断开与服务器或共享资源的所有先前连接,然后重试。 (HRESULT 异常:0x800704C3)

应用:System.DirectoryServices.AccountManagement

堆栈跟踪:在 System.DirectoryServices.AccountManagement.CredentialValidator.BindSam(字符串目标、字符串用户名、字符串密码)在 System.DirectoryServices.AccountManagement.CredentialValidator.Validate(字符串用户名,字符串密码)在 System.DirectoryServices.AccountManagement.PrincipalContext.ValidateCredentials(字符串用户名,字符串密码)在 MyNamespace.User..ctor(字符串用户名,字符串密码)

一旦错误发生,我会继续得到它,直到我重新启动我的整个服务器(不仅仅是 IIS)。我已经尝试重新启动我的应用程序池和/或 IIS,但在我重新启动机器之前错误不会消失。我还尝试为每次调用 ValidateCredentials(我不应该这样做)实例化(通过 using block )一个新的 PrincipalContext,但我最终还是遇到了同样的错误。根据我在 System.DirectoryServices.AccountManagement(msdn 文档、文章)上阅读的内容,我相信我使用正确,但这个错误正在削弱我的应用程序!我需要(并且应该能够)验证来自多个客户端的 Web 服务请求的本地用户凭据。难道我做错了什么?任何解决此问题的帮助将不胜感激...

最佳答案

  1. 此类型的任何公共(public)静态(在 Visual Basic 中共享)成员都是线程安全的”这个样板文本让很多人感到困惑。这意味着该类型公开的任何静态成员都是线程安全的。这并不意味着存储在静态成员中的类型的任何实例都是线程安全的。

  2. 您的 validateAdminCredentials 方法会创建一个新的 PrincipalContext 对象,然后继续使用静态 vpc 实例来验证凭据。由于您没有锁定对静态实例的访问,并且实例方法不是线程安全的,因此您最终会得到两个线程同时尝试访问同一个实例,这是行不通的。

尝试删除 vpc 字段并使用 principalContext 实例来验证凭据。您需要在每次调用时创建和处理 PrincipalContext

此外,您可以使用 IsMemberOf 方法来测试组中的成员资格,而不是手动迭代用户的组。

public static bool ValidateCredentials(string username, string password)
{
using (PrincipalContext principalContext = new PrincipalContext(ContextType.Machine))
{
return principalContext.ValidateCredentials(username, password);
}
}

public static bool validateAdminCredentials(string username, string password)
{
using (PrincipalContext principalContext = new PrincipalContext(ContextType.Machine))
{
if (principalContext.ValidateCredentials(username, password))
{
using (UserPrincipal user = UserPrincipal.FindByIdentity(principalContext, IdentityType.SamAccountName, username))
using (GroupPrincipal group = GroupPrincipal.FindByIdentity(principalContext, IdentityType.SamAccountName, "Administrators"))
{
if (null != group && user.IsMemberOf(group))
{
return true;
}
}
}

return false;
}
}

关于c# - 将 System.DirectoryServices.AccountManagement.PrincipalContext.ValidateCredentials 与 SAM 一起使用时出现奇怪错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/630566/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com