Erro ao usar o PrincipalContext.ValidateCredentials para autenticar em um computador local?
Eu tenho um serviço WCF que contém umLogin
método que valida um nome de usuário e senha com as credenciais da máquina local e, após um período de tempo aparentemente aleatório, ele deixará de funcionar para alguns usuários.
O comando de login real se parece com isto:
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;
}
Isso parece funcionar bem por alguns dias, então ele irá parar de funcionar abruptamente para alguns usuários e lançar essa exceção:
Várias conexões para um servidor ou recurso compartilhado pelo mesmo usuário, usando mais de um nome de usuário, não são permitidas. Desconecte todas as conexões anteriores com o servidor ou recurso compartilhado e tente novamente. (Exceção de HRESULT: 0x800704C3)
em System.DirectoryServices.AccountManagement.CredentialValidator.BindSam (String target, String userName, String password)
em System.DirectoryServices.AccountManagement.CredentialValidator.Validate (String userName, String password)
em System.DirectoryServices.AccountManagement.PrincipalContext.ValidateCredentials (String userName, String password)
em MyNamespace.LoginService.Login (nome de usuário String, senha String, endereço ip String) em C: \ Users \ me \ Desktop \ somefolder \ LoginService.svc.cs: linha 67
A linha 67 é:if (pContext.ValidateCredentials(username, password))
Não tenho certeza se isso importa ou não, mas a linha final da mensagem de erro é o caminho da solução VS na minha máquina de desenvolvimento, não o caminho para os arquivos no servidor de produção.
Quando ele falha, ele falha apenas para alguns usuários, enquanto outros podem continuar fazendo o login. A única coisa que eu encontrei para corrigir temporariamente o erro está em execuçãoiisreset
. Parar / iniciar o site ou reciclar o pool de aplicativos não funciona.
Eu não consigo reproduzir o erro sob demanda. Eu tentei fazer login com o mesmo usuário a partir de várias sessões e endereços IP, fazendo login com diferentes usuários da mesma sessão do navegador ao mesmo tempo, enviando spam pelo botão Login para tentar executá-lo várias vezes, etc. para funcionar bem.
Posso ver em nosso registro que os usuários conseguiram fazer login no passado:
3/21/2013 o 9:03a I logged in o 1:54p UserB logged in o 1:55p UserA logged in o 2:38p UserB logged in o 3:48p UserB logged in o 5:18p UserA logged in o 6:11p UserB logged in 3/22/2013 o 12:42p UserA logged in o 5:22p UserB logged in o 8:04p UserB logged in 3/25/2013 (today) o 8:47a I logged in o 12:38p UserB tries logging in and fails. Repeated ~15 times over next 45 min o 1:58p I login successfully o 2:08p I try to login with UserB's login info and fail with the same error
A razão pela qual nos autenticamos contra a máquina local é porque os usuários têm uma conta criada localmente para acesso FTP, e não queríamos criar nosso próprio sistema de login customizado ou fazer com que nossos usuários lembrassem dois conjuntos de credenciais.
O código só deve autenticar as credenciais do usuário e não faz mais nada com as credenciais do usuário. Não há outro código que useSystem.DirectoryServices
, nenhum arquivo IO em execução e nenhum acesso a qualquer coisa localmente no sistema de arquivos, exceto os arquivos necessários para executar o aplicativo da web.
O que pode fazer com que esse erro apareça, aparentemente aleatoriamente, depois de alguns dias? E como posso consertar isso?
O servidor é o Windows Server 2003, que executa o IIS 6.0, e é configurado para usar o .Net Framework 4.0