Разрешить вошедшему в систему пользователю вставлять в базу данных WPF

#c# #sql #sql-server #wpf

Вопрос:

Я хотел бы, чтобы вошедший в систему пользователь хранил данные в базе данных, которые будут видны только им. Нет ролей пользователей, только один тип пользователей, способных выполнять функции CRUD.

     public bool Create(SemesterDetails details)
    {
     
       SqlConnection  db = new SqlConnection(AppConnect.Connection);

        try
        {
            string  insModule = "INSERT INTO [Module](moduleCode,moduleName,modCredits,modHrsPerWeek)"  

          "VALUES('"   details.ModuleCode   "',  '"   details.ModuleName   "', '"   details.ModuleCredits   "', '"  details.ModuleStudyHrs  "')";
            if (db.State == ConnectionState.Closed)
            {
                db.Open();

                command = new SqlCommand(insModule,db);
                int i = command.ExecuteNonQuery();
                if (i>0)
                {
                   return true;
                }
                db.Close();
            }

        }
        catch (Exception exc)
        {

            Console.WriteLine(exc.Message);            
        }
        return false;
    }
 

Приведенный выше код вставляет значения в базу данных.

Комментарии:

1. Какие СУБД вы используете?

2. Использование MSSQL ADO.net

3. Научитесь параметризовать свои запросы — пишите более безопасный код! Узнайте больше USING — напишите лучший код на c#.

4. Вам нужно исправить эту огромную дыру в безопасности в вашем коде. Прекратите вводить значения в свои утверждения. Сейчас уже не 90-е; учитесь на глупых ошибках других людей.

5. Если вам нужны строки, которые могут быть видны только пользователю, вам необходимо изучить Безопасность на уровне строк (RLS).

Ответ №1:

В зависимости от вашей версии (пожалуйста, всегда указывайте!), безопасность на уровне строк, вероятно, является той функцией, которую вы ищете, но обратите внимание, что существует измеримое влияние на производительность, а также некоторые другие предостережения.

Упрощенным способом сделать это для будущих строк может быть добавление нового столбца со значением по умолчанию:

 BEGIN TRANSACTION;

-- let's add a column to capture the creator
-- (for a brief moment, this will be you):
ALTER TABLE dbo.Module 
  ADD OwningPerson nvarchar(128) NOT NULL
  DEFAULT SUSER_SNAME();
GO

-- now let's make existing rows visible to all
-- (but you can go back and update them manually):
UPDATE dbo.Module SET OwningPerson = N'legacy';

COMMIT TRANSACTION;
 

Теперь, если вы вставите новую строку, этот столбец будет иметь значение контекстного пользователя.

Затем, чтобы убедиться, что пользователи могут видеть только свои собственные строки, вы можете запретить выбор в таблице и заставить их прочитать это представление (здесь может пригодиться роль на уровне базы данных).:

 CREATE VIEW dbo.OnlyMyModules
AS
  SELECT <cols> 
    FROM dbo.Module 
    WHERE OwningPerson IN (N'legacy', SUSER_SNAME());
 

(Или, может быть, вы хотите запретить пользователям просматривать устаревшие модули до тех пор, пока вы не сможете вернуться и правильно назначить их пользователям.)

Вы также должны создать (и защитить) хранимую процедуру, чтобы вы/администраторы могли извлекать строки для любого пользователя:

 CREATE PROCEDURE dbo.CheckUserModules
  @username nvarchar(128)
AS
BEGIN
  SET NOCOUNT ON;

  SELECT <cols> 
    FROM dbo.Module 
    WHERE OwningPerson = @username;
END
 

Комментарии:

1. Привет @Аарон Бертран, это работает, но это дает имя моего компьютера как владельца

2. @Jacob SUSER_SNAME() возвращает имя вашего компьютера? Это интересно, как именно вы подключаетесь к SQL Server? Попробуйте использовать явного пользователя с проверкой подлинности SQL или свою учетную запись Windows, или как будут подключаться ваши пользователи и/или приложение. Есть несколько других функций идентификатора безопасности, которые вы также можете попробовать, например ORIGINAL_LOGIN , CURRENT_USER , USER_NAME , и т.д. SESSION_USER

3. ^ попробуйте SELECT SUSER_SNAME(), ORIGINAL_LOGIN(), CURRENT_USER, USER_NAME(), SESSION_USER; как вы, так и в контексте того, что делает ваше приложение, чтобы вы могли решить, какая функция безопасности будет работать.

4. Я имел в виду, что он дает мне имя пользователя SQL, а не имя пользователя, введенное пользователем

5. @Jacob вы имеете в виду, что пользователь предоставляет свое имя пользователя? Если имя пользователя доступно вам в коде C#, то вы можете просто добавить новый столбец в инструкцию insert (но, пожалуйста, параметрируйте эту вещь, а затем добавьте 5-й параметр для нового столбца).