Batflash Ответов: 1

Блокировка пользователя после неудачного количества попыток в C#


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

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

В настоящее время это мой код.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Data.OleDb;

namespace FinalAssignment
{
    public partial class SignUp_and_Login : Form
    {
        private OleDbConnection connection = new OleDbConnection();
        public SignUp_and_Login()
        {
            InitializeComponent();
            connection.ConnectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\Lenovo\Desktop\DDOOCP Assignment\Sign up and Login.accdb;Persist Security Info=False;";
        }

        private void CmdSubmit_Click(object sender, EventArgs e)
        {
            connection.Open();
            OleDbCommand command = new OleDbCommand();
            command.Connection = connection;
            command.CommandText = "insert into SignUp ([First Name], [Last Name], [Username], [Email Address], [Password]) values('" + txtFirstName.Text + "','" + txtLastName.Text + "','" + txtUser.Text + "','" + txtEmail.Text + "','" + txtPass.Text + "')";
            command.ExecuteNonQuery();
            MessageBox.Show("Sign up successful.");
            new Form().Show();
            this.Hide();
            connection.Close();
        }

        private void SignUp_and_Login_Load(object sender, EventArgs e)
        {
            connection.Open();

            connection.Close();
        }

        private void CmdLogin_Click(object sender, EventArgs e)
        {
            connection.Open();
            OleDbCommand command = new OleDbCommand();
            command.Connection = connection;
            command.CommandText = "select * from SignUp where Username = '" + txtUsername.Text + "' and Password = '" + txtPassword.Text + "'";
            OleDbDataReader reader = command.ExecuteReader();
            int count = 0;
            while (reader.Read())
            {
                count = count + 1;
            }
            if (count == 1)
            {
                MessageBox.Show("The Username and Password are correct.");
            }
            else if (count > 1)
            {
                MessageBox.Show("The Username and Password have been duplicated. Please try again.");
            }
            else
            {
                MessageBox.Show("Either the Username or Password entered is incorrect. Please try again.");
            }
            connection.Close();
        }
    }
}

1 Ответов

Рейтинг:
1

OriginalGriff

Во-первых, не делай этого так! Никогда не объединяйте строки для построения команды SQL. Это оставляет вас широко открытыми для случайной или преднамеренной атаки SQL-инъекции, которая может уничтожить всю вашу базу данных. Вместо этого всегда используйте параметризованные запросы.

Когда вы объединяете строки, вы вызываете проблемы, потому что SQL получает такие команды, как:

SELECT * FROM MyTable WHERE StreetAddress = 'Baker's Wood'
Цитата, добавленная пользователем, завершает строку в том, что касается SQL, и вы получаете проблемы. Но могло быть и хуже. Если я приду и наберу вместо этого: "x';DROP TABLE MyTable;--", то SQL получит совсем другую команду:
SELECT * FROM MyTable WHERE StreetAddress = 'x';DROP TABLE MyTable;--'
Которые SQL видит как три отдельные команды:
SELECT * FROM MyTable WHERE StreetAddress = 'x';
Совершенно правильный выбор
DROP TABLE MyTable;
Вполне допустимая команда "удалить таблицу"
--'
А все остальное-это комментарии.
Так оно и происходит: выбирает любые совпадающие строки, удаляет таблицу из базы данных и игнорирует все остальное.

Поэтому всегда используйте параметризованные запросы! Или будьте готовы часто восстанавливать свою БД из резервной копии. Вы ведь регулярно делаете резервные копии, не так ли?

И оставить себя широко открытым для SQL-инъекции на экране входа в систему? Это просто самоубийство ...

Во-вторых... Никогда не храните пароли в открытом виде - это серьезная угроза безопасности. Здесь есть некоторая информация о том, как это сделать: Хранение паролей: как это сделать.[^]

И помните: если это веб-сайт и у вас есть какие-либо пользователи из Европейского союза, то применяется GDPR, а это означает, что вы должны обрабатывать пароли как конфиденциальные данные и хранить их безопасным и безопасным способом. Текст-это ни то, ни другое, и штрафы могут быть ... ГМ ... выдающийся. В декабре 2018 года немецкая компания получила относительно низкий штраф в размере 20 000 евро именно за это.

В-третьих, никогда не используйте SELECT * FROM - всегда перечисляйте столбцы, которые вы хотите вместо этого. В этом случае вам даже не нужен DataReader: SELECT COUNT(*) FROM позволит вам использовать ExecuteScalar и возвращать счетчик напрямую.

Наконец, если вы получаете сбой, вы подсчитываете его и сохраняете счетчик в БД против идентификатора пользователя. Если он превышает допустимый уровень, вы блокируете учетную запись от всех Логинов. Когда вы получаете успешный вход в систему, вы сбрасываете счетчик.


Batflash

Окей. Большое вам спасибо за вашу помощь. Я действительно ценю это. Хотя, как мне сделать эту блокировку? Будет ли это в базе данных или в моем коде?

OriginalGriff

Оба. Он хранится в базе данных, проверен в коде.