#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-й параметр для нового столбца).