- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我有一个包含 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.
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/
我有一个带有 Windows 身份验证的 Web 应用程序。当我调试线路时 var domainContext = new PrincipalContext(ContextType.Domain, "
我正在开发一个 C# .NET Framework 库来访问事件目录。 我必须做的一件事是获取所有 AD 用户,我看到了: PrincipalContext principalContext =
我正在尝试使用 PrincipalContext 检查远程计算机上是否存在本地用户组。 我在使用 PrincipalContext 时遇到问题: PrincipalContext ctx = new
我正在尝试将 PrincipalContext 用于我正在开发的网络服务。我已经在不同应用程序的 Web 服务器上使用表单例份验证,并且工作正常。 我收到的错误是: System.DirectoryS
using (PrincipalContext ctx = new PrincipalContext(ContextType.Domain, Domain, UserName, Password))
首先,我查看了关于 SO 的大多数问题,但似乎都不是完全相同的问题。 Here是一个类似的问题,但并不完全相同。在我的情况下,我正在创建一个 PrincipalContext : Dim pctx A
我正在尝试使用 PrincipalContext 通过 Active Directory 服务找出域组件。 我使用很少的参数创建了 PrincipalContext: PrincipalContext
我正在尝试使用 PrincipalContext 通过 Active Directory 服务找出域组件。 我使用很少的参数创建了 PrincipalContext: PrincipalContext
每当调用此方法时,我都会崩溃。 public bool findSAMAccountByName(string environmentUserName) { try
应用程序能否创建一次 PrincipalContext,然后在应用程序的整个生命周期内重复使用它?这将避免在每次调用 Active Directory 之前使用相同的详细信息重新创建 Principa
我们有一个应用程序使用 LDAP 通过 IP 地址通过 VPN 隧道对远程 AD 进行身份验证,使用以下代码: using (PrincipalContext pc = new PrincipalCo
我知道这有一个简单的解决方案,但我似乎无法让它工作... 使用其他 Stack Overflow answers和 Microsoft's Documentation ,我知道 PrincipalCo
我正在为 asp.net 创建一个自定义登录功能,它根据事件目录进行验证。用户必须能够仅使用他的用户名或他的用户名和域(以及两种情况下的密码)登录。 代码: AuthUser user = Authe
我有一个返回 PrincipalServer 的方法 CreateContextForGlobalCatalog连接到全局目录: PrincipalContext = new PrincipalCon
我有一个包含很多属性的 UserPrincipal 对象,但我找不到密码过期日期的属性。 如何做到这一点? 最佳答案 这是我能想到的最简单的方法... using System.DirectorySe
有没有办法强制 PrincipalContext 连接到特定的域 Controller ?我正在为我的应用程序枚举锁定帐户列表,我希望能够查询多个服务器并从所有 DC 返回列表。 目前我得到我的 Pr
我正在尝试将域帐户添加到远程计算机的管理员组。我遇到的问题是,当我尝试实际连接到远程机器 PrincipleContext 时,它给了我一条访问被拒绝的消息,但我是以远程机器本地管理员的身份连接的。当
我有以下两个使用 LDAP 和 LDAPS 对用户进行身份验证的实现,我想知道哪个更好/更正确。作为记录,这两种方法都适用于 SSL 和非 SSL 连接。 我也很好奇,因为在 Non-SSL Prin
我正在尝试通过 Active Directory 中的用户名查找用户。 这个有效: const string Domain = "SLO1.Foo.Bar.biz"; const string Use
我正在创建一个 PrincipalContext 对象,用于从我们的 AD 数据库中检索用户的组(然后我们使用这些对象对站点的各个部分进行身份验证)。 这过去是使用表单例份验证完成的,所以代码看起来像
我是一名优秀的程序员,十分优秀!