private async Task <SignInResultCustom> TenantSignInAsync(Tenant tenant, string username, string password, bool isPersistent = false, bool lockoutOnFailure = false) { var user = await UserManager.FindByNameAsync(tenant.Id, username); var ldapEnabled = await _directoryManager.CheckForLdapSupport(tenant); var passwordSuccess = false; // Local users will immediately succeed if the password matches // NOTE: Skip if password hash is null since local users can't have null passwords if (user != null && user.PasswordHash != null) { passwordSuccess = VerifyPasswordHash(user, password); } // If user could not be signed in locally then let's try ldap if (ldapEnabled && !passwordSuccess) { var ldapUser = await LdapSignInAsync(tenant, username, password); if (ldapUser != null) { // Success, ldap user found.... // Sync the user and sign in using external auth scheme user = await SyncUserWithLdap(user, ldapUser); await SignInAsync(user, isPersistent, "Ldap"); return(SignInResultCustom.Success(user)); } } // fail if the user could not be found if (user == null) { return(SignInResultCustom.Failed()); } // Return any abnormal user states only if the user supplied the correct password if (passwordSuccess) { if (user.MustChangePassword) { return(SignInResultCustom.ChangePasswordRequired(user)); } // fail if the user's email address has not been confirmed (custom) if (!user.EmailConfirmed) { return(SignInResultCustom.EmailNotConfirmed()); } } // If we get this far then continue processing using base SignInManager to handle // two factor authentication, lockout policies, and password rehashing var baseResult = await PasswordSignInAsync(user, password, isPersistent, lockoutOnFailure); return(new SignInResultCustom(user, baseResult)); }