通过网络验证本地用户

时间:2011-03-30 21:11:35

标签: c# .net security authentication

我正在尝试根据提供的用户名和密码对本地用户进行身份验证。我遇到了这个帖子:Validate a username and password against Active Directory?

以下是我验证用户的方式:

PrincipalContext pc = new PrincipalContext(ContextType.Machine);
bool isValid = pc.ValidateCredentials(user, pass);

只要我在网络上,它就可以正常工作,但如果我断开电脑,它就会给我:

  

找不到网络路径。

我要做的就是在本地机器上验证,这可能是也可能不是网络的一部分。

编辑:UserPrincipal.FindByIdentity似乎仍然没有AD,这是给我带来麻烦的pc.ValidateCredentials。

4 个答案:

答案 0 :(得分:2)

您应该查看以下链接:How to validate domain credentials?

如果您必须能够在AD不在线的情况下完成验证,那么使用LogonUser Win32 API函数似乎是唯一的选择。然而,并非没有严重的缺点(如线程中所示)。您需要使用许多权限对执行您的应用的帐户进行皮条客。

答案 1 :(得分:2)

正如您所指出的,System.DirectoryServices命名空间在断开连接的上下文中并不是非常有用 - 您需要与LSA进行通信,而不是与其Active Directory父进行通信。

我不知道与advapi32.LogonUser对应的官方.Net API,但您可以调用它来验证本地缓存的登录。但是,如果计算机具有网络访问权限但无法查看域控制器,则可能需要一段时间才能返回。

如果你想通过P / Invoke调用它,函数有一个declaration on pinvoke.net。 (但我没有审核过;我发现pinvoke.net上的签名质量差异很大。)

答案 2 :(得分:1)

可能的丑陋解决方法 -

将ValidateCredentials()与ContextType.Machine一起使用将始终首先检查本地系统的凭据。如果未在本地找到凭据,它仅执行网络活动。你可以捕获PrincipalOperationException,如果抛出并安全地忽略它,知道如果方法到目前为止,凭证无效。

答案 3 :(得分:0)

bool valid = false;
using (PrincipalContext checkpass = new PrincipalContext(ContextType.Machine)) //checks local machine first
{
  try // you need to use try catch when you only have local user
  {
      valid = checkpass.ValidateCredentials(user, password);
  }
  catch (Exception ex) { valid = true; }
  if (valid)
  {
       // returns ok   
  }
  else
  {
      // returns false
  }