Detectar se uma conta de Utilizador de directório activo está bloqueada com o LDAP em Python
estou a validar os logins do utilizador usando o módulo ldap do python. Quando o login falhar, recebo um ldap.INVÁLID_CREDENTIALS login, but this can be either because of a wrong password or because the account is locked. A conta fica bloqueada depois da terceira tentativa.
gostaria de detectar que a conta está bloqueada e comunicar isso ao utilizador frustrado, em vez da mesma mensagem de "autenticação inválida".
à procura de uma solução que encontrei:
- o controlo de conta do utilizador bloqueado a referência não é utilizada pelo AD;
- o atributo lockoutTime deve ser usado em vez de
a pesquisa LDAP que devo usar para encontrar utilizadores bloqueados é:
(&(objectClass=user)(lockoutTime>=1))
ou para um utilizador específico:
(&(objectClass=user)(sAMAccountName=jabberwocky)(lockoutTime>=1))
mas isto não está a funcionar, a consulta não retorna resultados Todas as vezes.
6 answers
Um valor de zero em lockoutTime
significa que não está trancado. Devias experimentar isto.
(&(objectClass=user)(!lockoutTime=0))
Na verdade, a consulta acima ainda não está 100% correta. Se ler a impressão fina do MSDN, a Microsoft está a sugerir que adicione o atributo Lockout-Time
ao atributo Lockout-Duration
e depois o compare com a hora actual. Isso é porque existe uma coisa chamada Duração do lockout. Uma vez que a duração do bloqueio passa, o Usuário é desbloqueado automaticamente. Zero em Lockout-Duration
significa que a conta está bloqueada para sempre até o administrador o desbloquear.
Ver este artigo MSDN
Este valor do atributo só é reposto quando a conta está ligada correctamente. Isto significa que este valor pode não ser zero, mas o a conta não está bloqueada. Para determinar com precisão se a conta é bloqueado, você deve adicionar a duração do Lockout a este tempo e comparar o resultado para o tempo atual, contabilizando fusos horários locais e verao tempo.
lockoutTime
é um atributo <not set>
por isso a maneira mais fácil é usar:
(&(objectClass=user)(lockoutDuration=*)))
Para as entradas não vazias.
Actualizar:
No entanto, este valor também é definido quando a senha expirar, a senha precisa de mudar, etc.
Por isso, tem de ser filtrado por:UserPrincipal userPrincipal = new UserPrincipal(context);
bool isLocked = userPrincipal.IsAccountLockedOut();
Para obter os casos em que o Utilizador está bloqueado porque violou a Política de senha, p.ex. introduziu incorrectamente a senha 5 vezes.
Além disso, descobri que o tempo de bloqueio não é garantido para todos os utilizadores no anúncio (pelo menos na nossa configuração), mas será criado ao atingir o número de tentativas de bloqueio falhadas. Assim, na verificação de contas bloqueadas, a verificação de nenhuma ou um equivalente será necessária também.
Use esta consulta para obter os melhores resultados,
Get-ADUser-LDAPFilter "(&(objectCategory=Person) (objectClass=User) (lockoutTime>=1)) " - Properties LockedOut
Também encontrei esta lista de opções de propriedades: Como usar as opções de controlo de Contas Do Utilizador
SCRIPT 0x0001 1
ACCOUNTDISABLE 0x0002 2
HOMEDIR_REQUIRED 0x0008 8
LOCKOUT 0x0010 16
PASSWD_NOTREQD 0x0020 32
PASSWD_CANT_CHANGE 0x0040 64
ENCRYPTED_TEXT_PWD_ALLOWED 0x0080 128
TEMP_DUPLICATE_ACCOUNT 0x0100 256
NORMAL_ACCOUNT 0x0200 512
INTERDOMAIN_TRUST_ACCOUNT 0x0800 2048
WORKSTATION_TRUST_ACCOUNT 0x1000 4096
SERVER_TRUST_ACCOUNT 0x2000 8192
DONT_EXPIRE_PASSWORD 0x10000 65536
MNS_LOGON_ACCOUNT 0x20000 131072
SMARTCARD_REQUIRED 0x40000 262144
TRUSTED_FOR_DELEGATION 0x80000 524288
NOT_DELEGATED 0x100000 1048576
USE_DES_KEY_ONLY 0x200000 2097152
DONT_REQ_PREAUTH 0x400000 4194304
PASSWORD_EXPIRED 0x800000 8388608
TRUSTED_TO_AUTH_FOR_DELEGATION 0x1000000 16777216
PARTIAL_SECRETS_ACCOUNT 0x04000000 67108864
Você deve fazer um binário-e de propriedade userAccountControl
com 0x002
. Para obter todas as contas bloqueadas (isto é, desactivadas), pode usar
(&(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=2))
Para o operador 1.2.840.113556.1.4.803
ver Regras de correspondência LDAP
(&(objectClass=utilizador) (&(lockoutTime=*) (!(tempo de bloqueio=0))))
Irá devolver os objectos que são Utilizadores e tem um atributo actual chamado lockoutTime que não é igual a 0.