使用PrincipalContext.ValidateCredentials对本地计算机进行身份validation时出错?

我有一个WCF服务,其中包含一个Login方法,该方法根据本地计算机凭据validation用户名和密码,并且在看似随机的一段时间后,它将停止为某些用户工作。

实际的登录命令如下所示:

 public UserModel Login(string username, string password, string ipAddress) { // Verify valid parameters if (username == null || password == null) return null; try { using (var pContext = new PrincipalContext(ContextType.Machine)) { // Authenticate against local machine if (pContext.ValidateCredentials(username, password)) { // Authenticate user against database using (var context = new MyEntities(Connections.GetConnectionString())) { var user = (from u in context.Users where u.LoginName.ToUpper() == username.ToUpper() && u.IsActive == true && (string.IsNullOrEmpty(u.AllowedIpAddresses) || u.AllowedIpAddresses.Contains(ipAddress)) select u).FirstOrDefault(); // If user failed to authenticate against database if (user == null) return null; // Map entity object to return object and assign session token var userModel = Mapper.Map(user); userModel.Token = Guid.NewGuid(); userModel.LastActivity = DateTime.Now; // Authenticated users are added to a list on the server // and their login expires after 20 minutes of inactivity authenticatedUsers.Add(userModel); sessionTimer.Start(); // User successfully authenticated, so return UserModel to client return userModel; } } } } catch(Exception ex) { // This is getting hit MessageLog.WriteMessage(string.Format("Exception occurred while validating user: {0}\n{1}", ex.Message, ex.StackTrace)); return null; } // If authentication against local machine failed, return null return null; } 

这似乎可以正常工作几天,然后它会突然停止为某些用户工作并抛出此exception:

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

at System.DirectoryServices.AccountManagement.CredentialValidator.BindSam(String target,String userName,String password)

at System.DirectoryServices.AccountManagement.CredentialValidator.Validate(String userName,String password)

at System.DirectoryServices.AccountManagement.PrincipalContext.ValidateCredentials(String userName,String password)

at MyNamespace.LoginService.Login(String username,String password,String ipAddress)在C:\ Users \ me \ Desktop \ somefolder \ LoginService.svc.cs:第67行

第67行是: if (pContext.ValidateCredentials(username, password))

我不确定它是否重要,但错误消息的最后一行是我的开发机器上VS解决方案的路径,而不是生产服务器上文件的路径。

当它失败时,它只对某些用户失败,而其他用户可以继续正常登录。 我发现暂时修复错误的唯一办法是运行iisreset 。 停止/启动网站或回收应用程序池不起作用。

我无法按需重现错误。 我尝试使用来自多个会话和IP地址的同一用户登录,同时使用同一浏览器会话中的不同用户登录,向“登录”按钮发送垃圾邮件以尝试让其多次运行等,但所有内容都会显示工作正常。

我可以从我们的日志记录中看到用户已成功登录过去:

 2013年3月21日
 o 9:03a我登录了
 o 1:54p UserB已登录
 o 1:55p UserA已登录
 o 2:38p UserB已登录
 o 3:48p UserB已登录
 o 5:18p UserA已登录
 o 6:11p UserB已登录

 2013年3月22日
 o 12:42p UserA已登录
 o 5:22p UserB已登录
 o 8:04p UserB已登录

 2013年3月25日(今天)
哦8:47a我登录了
 o 12:38p UserB尝试登录并失败。 在接下来的45分钟内重复约15次
 o 1:58p我成功登录
 o 2:08p我尝试使用UserB的登录信息登录,但失败并出现同样的错误

我们对本地计算机进行身份validation的原因是因为用户在本地创建了一个用于FTP访问的帐户,我们不想构建自己的自定义登录系统或让我们的用户记住两组凭据。

代码应仅validation用户的凭据,并且不会对用户的凭据执行任何其他操作。 没有其他代码使用System.DirectoryServices ,没有文件IO正在进行,并且除了运行Web应用程序所需的文件之外,无法访问文件系统上的任何本地内容。

几天之后,看似随意出现的错误会导致什么? 我该如何解决?

服务器是运行IIS 6.0的Windows Server 2003,并且设置为使用.Net Framework 4.0

我能在网上找到最接近解释这个问题的是这个论坛post ,用户遇到相同的错误并得到重播说明:

WinNT提供程序在服务器环境中表现不佳。 我真的很惊讶你没有看到这个负载小得多。 我只能用2或3个用户获得此function。

这个SO评论说

正确validation某人的最佳方法是使用LogonUserAPI作为@stephbu写入。 本文中描述的所有其他方法都不会100%工作

其中“所有其他方法”包括使用PrincipalContext.ValidateCredentials的最高投票答案

听起来像PrincipalContext.ValidateCredentials在Windows Server 2003和IIS6.0上并不是完全可靠的,所以我重写了我的身份validation代码以使用LogonUser WinAPI方法。

 [DllImport("advapi32.dll", SetLastError = true)] public static extern bool LogonUser( string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr phToken ); IntPtr hToken; if (LogonUser(username, "", password, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, out hToken)) { ... }