gpt4 book ai didi

c# - 使用 PrincipalContext.ValidateCredentials 对本地计算机进行身份验证时出错?

转载 作者:可可西里 更新时间:2023-11-01 09:13:46 28 4
gpt4 key购买 nike

我有一个包含 Login 的 WCF 服务根据本地计算机凭据验证用户名和密码的方法,在看似随机的一段时间后,它将停止对某些用户起作用。

实际的登录命令是这样的:

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>(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;
}

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

Multiple connections to a server or shared resource by the same user, using more than one user name, are not allowed. Disconnect all previous connections to the server or shared resource and try again. (Exception from HRESULT: 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) in C:\Users\me\Desktop\somefolder\LoginService.svc.cs:line 67

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

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

失败时,只是部分用户失败,其他用户可以继续登录就好了。我发现暂时修复错误的唯一方法是运行 iisreset .停止/启动网站或回收应用程序池不起作用。

我无法按需重现错误。我尝试过使用来自多个 session 和 IP 地址的同一用户登录,同时使用来自同一浏览器 session 的不同用户登录,发送垃圾邮件登录按钮以尝试让它运行多次,等等,但一切都出现了工作正常。

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

3/21/2013o   9:03a   I logged ino   1:54p   UserB logged ino   1:55p   UserA logged ino   2:38p   UserB logged ino   3:48p   UserB logged ino   5:18p   UserA logged ino   6:11p   UserB logged in3/22/2013o   12:42p  UserA logged ino   5:22p   UserB logged ino   8:04p   UserB logged in3/25/2013 (today)o   8:47a   I logged ino   12:38p  UserB tries logging in and fails. Repeated ~15 times over next 45 mino   1:58p   I login successfullyo   2:08p   I try to login with UserB's login info and fail with the same error

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

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

是什么原因导致该错误在几天后看似随机出现?我该如何解决?

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

最佳答案

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

The WinNT provider does not do well in a server environment. I am actually suprised you don't see this with a much smaller load. I have been able to get this with only 2 or 3 users.

this SO comment说明

The BEST way to correctly authenticate someone is to use LogonUserAPI as @stephbu write. All other methods described in this post will NOT WORK 100%

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

听起来 PrincipalContext.ValidateCredentials 在 Windows Server 2003 和 IIS6.0 上并不是完全 100% 可靠的,所以我重写了我的身份验证代码以使用 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))
{
...
}

关于c# - 使用 PrincipalContext.ValidateCredentials 对本地计算机进行身份验证时出错?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15622304/

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