Member 13111663 Ответов: 2

Как ограничить пользователя после 3 неудачных попыток входа в форму входа в C#


private void button1_Click(object sender, EventArgs e)
        {

            if (txtuser.Text == "" && txtpass.Text == "")
            {
                MessageBox.Show("USERNAME and PASSWORD cannot be blank");
                txtuser.Focus();
            }
            else
            {
                SqlConnection cn = new SqlConnection("Data Source=XYZ;Initial Catalog=CRMS;Integrated Security=True");

                cn.Open();
                SqlCommand cmd = new SqlCommand("select * from login where username = '" + txtuser.Text + "' and password = '" + txtpass.Text + "'", cn);
                SqlDataReader dr;
                dr = cmd.ExecuteReader();


                int count = 0;
                while (dr.Read())
                {
                    count += 1;
                }

                if (count == 1)
                {
                    MessageBox.Show("WELCOME!", "Message", MessageBoxButtons.OK, MessageBoxIcon.Information);
                   
                    Home h = new Home();
                    h.Show();
                    this.Hide();


                }
                else if (count >= 0)
                {
                    MessageBox.Show("Wrong Username or Password", "Message", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }

                cn.Close();

                txtuser.Clear();
                txtpass.Clear();
            }
        }


Что я уже пробовал:

Приведенный выше код работает, и никаких проблем вообще нет. Что мне нужно, так это ограничить пользователя после 3 неудачных попыток, и приложение выйдет. Я действительно не знаю, где это реализовать. Любой может помочь, пожалуйста, мне это очень нужно.
Заранее благодарю вас!

PIEBALDconsult

Пожалуйста, используйте параметризованные операторы; не используйте конкатенацию строк для вставки значений в команду.
И, пожалуйста, не помещайте код доступа к данным непосредственно в свой пользовательский код.

Dave Kreskowiak

Что делать, если пользователь вводит пароль, но не имя пользователя? Ваше заявление IF не объясняет ни эту ситуацию, ни наоборот.

Richard Deeming

И вы храните пароли в виде простого текста. Вы должны всегда хранить только соленый хэш пароля пользователя.

Безопасная Аутентификация Паролем Объясняется Просто[^]
Соленое хеширование паролей - все правильно[^]

2 Ответов

Рейтинг:
2
Рейтинг:
19

Mehedi Shams

Привет,

Ниже приводится измененная версия вашего кода в соответствии с вашими потребностями:

1) переместите счетчик на глобальный уровень формы.
2) Вы можете использовать "HasRows" считывателя данных, чтобы увидеть, было ли найдено совпадение.

// Move the counter at a global level for the form.
int count = 1;
private void button1_Click(object sender, EventArgs e)
{

    if (txtuser.Text == "" && txtpass.Text == "")
    {
        MessageBox.Show("USERNAME and PASSWORD cannot be blank");
        txtuser.Focus();
    }

    else
    {
        SqlConnection cn = new SqlConnection("Data Source=LAPTOP-SO38VH6F;Initial Catalog=CRMS;Integrated Security=True");
        cn.Open();

        SqlCommand cmd = new SqlCommand("select * from login where username = '" + txtuser.Text + "' and password = '" + txtpass.Text + "'", cn);
        SqlDataReader dr;
        dr = cmd.ExecuteReader();
                
        if (dr.HasRows) // HasRows = true would imply the loging was found.
        {
            MessageBox.Show("WELCOME!", "Message", MessageBoxButtons.OK, MessageBoxIcon.Information);

            cn.Close(); // Close connection
            Home h = new Home();
            h.Show();
            this.Hide();
        }
        else
        {
            if (count++ >= 3)
            {
                MessageBox.Show("Failed in 3 login attempts. Assuming unauthorized access. Terminating!", "Message", MessageBoxButtons.OK, MessageBoxIcon.Error);
                Application.Exit();
            }

            // This is the ELSE part - not terminating yet, but offering 3 attempts.
            MessageBox.Show("Wrong Username or Password", "Message", MessageBoxButtons.OK, MessageBoxIcon.Error);

            cn.Close(); // Close connection
            txtuser.Clear();
            txtpass.Clear();
        }
    }
}
Некоторые предложения по улучшению кода:

1) заверните в TRY-CATCH.
2) похоже, что вы храните пароль так, как он есть в базе данных. Пожалуйста, используйте шифрование для хранения и извлечения.
3) Разумные SQL-Инъекции. Лучше передайте имя пользователя и пароль хранимой процедуре или функции SQL, которая вернет YES/NO.


Member 13111663

Ваш код верен, большое вам спасибо! это сработало для меня, Спасибо, брат!

Mehedi Shams

Спасибо, рад, что это помогло :)!

Nirav Prabtani

+5 за ваши усилия.

Просто убедитесь, что пользователи не будут делать свою домашнюю работу самостоятельно.

Mehedi Shams

Спасибо, Нирав, я буду иметь это в виду.

Richard Deeming

"Лучше передайте имя пользователя и пароль хранимой процедуре или функции SQL, которая вернет YES/NO."

Использование хранимой процедуры или функции не защитит от SQL-инъекции. Вместо этого вы должны использовать параметризованные запросы.

Mehedi Shams

Спасибо Ричарду за поправку, это правильно.

Richard Deeming

"Пожалуйста, используйте шифрование для хранения и извлечения."

Нет-только когда-либо храните криптографический хэш соленого пароля, используя уникальный хэш для каждой записи.

Безопасная Аутентификация Паролем Объясняется Просто[^]
Соленое хеширование паролей - все правильно[^]

"Шифрование" обычно используется для обозначения "обратимого шифрования", которое почти так же плохо, как и обычный текст. :)

Mehedi Shams

Спасибо, Ричард, это тоже хорошее предложение. Спасибо за ссылки.