Как безопасно настроить подключение к базе данных
похожие, но не то же самое:
- как безопасно хранить данные подключения к базе данных
- безопасное подключение к базе данных в приложении
Привет всем, у меня есть приложение c# WinForms, подключающееся к серверу баз данных. Строка подключения к базе данных, включая общий пользователь / пропуск, помещается в файл конфигурации NHibernate, который находится в том же каталоге, что и exe-файл.
Теперь Я есть эта проблема: пользователь, который запускает приложение, не должен знать имя пользователя/пароль пользователя общей базы данных, потому что я не хочу, чтобы он рылся в базе данных напрямую.
в качестве альтернативы я мог бы жестко закодировать строку подключения, что плохо, потому что администратор должен иметь возможность изменить ее, если база данных перемещена или если он хочет переключаться между средами dev/test/prod.
Так долго я нашел три возможности:
-
на первый ссылочный вопрос обычно отвечал сделать файл читаемым только для пользователя, который запускает приложение.
но этого недостаточно в моем случае (пользователь, запускающий приложение, является человеком. Пользователь/пропуск базы данных являются общими и даже не должны быть доступны человеку.)
-
первый ответ дополнительно предлагается шифрование данных подключения перед записью в файл.
при таком подходе администратор больше не может настроить строку подключения, потому что он не может зашифровать ее вручную.
на вторая ссылка вопрос обеспечивает подход для этого самого сценария, но он кажется очень сложным.
мои вопросы к вам:
Это очень общая проблема, так что нет любой общий способ "как это сделать", каким-то образом"шаблон дизайна"?
есть некоторые поддержки .Инфраструктура чистый конфиг?
(необязательно, возможно, вне области) Могу ли я легко объединить это с механизмом конфигурации NHibernate?
обновление:
в ответ на первые ответы: есть несколько причин, по которым я хотел бы подключиться к базе данных напрямую и не использовать веб сервис:
- (N)Hibernate можно использовать только с базой данных, а не с веб-сервисами (я прав?)
- мы планируем предоставить автономную возможность, т. е. если база данных или сеть должны быть отключены, пользователь может продолжить свою работу. Чтобы управлять этим, я думаю о наличии локальной базы данных в proc, например SQL Server Compact, и использовании MS Sync framework для синхронизации ее с базой данных сервера, как только она снова появится.
У вас есть еще идеи, учитывающие это?
4 ответов
на самом деле подход WebService (упомянутый в другом ответе) означает, что вы перемещаете NHibernate и его логику в веб-сервис. Затем WebService предоставляет функции БД, доступные приложению, используя методы WebService.
существует практически только один пользователь для базы данных, тот, который использует веб-сервис, и если вы хотите, чтобы пользователь приложения имел разные привилегии БД, вы абстрагируете его от уровня веб-сервиса
в конце, приложение WinForms знает только местоположение веб-службы, где оно запрашивает данные с помощью методов веб-службы, и вы можете применить любую необходимую меру безопасности между этими двумя конечными точками.
для автономных возможностей все сводится к созданию безопасного способа сохранения ваших данных в локальное хранилище и предоставлению метода синхронизации через WebService
я действительно сделал это, используя веб-сервис, который связывался с БД и WinForm приложение (.NET Compact Framework), которое только разговаривало с веб-сервисом, и в случае отсутствия покрытия сотовой сети оно сериализует изменения на карте памяти (данные не были важны, поэтому для моего случая неясные/непристойные меры безопасности, где не приняты)
обновление с небольшим примером по запросу (я нахожу это странным, хотя попросить пример об этом)
вы настроили свои классы домена и конфигурацию nhibernate и (например) свой репозиторий материал в проекте типа ASP.NET приложение WebService. Для простоты у меня будет только один класс веб-сервиса Foo
(in Foo.службы ASMX.cs), а также один Bar
доменный класс
Итак, вы получаете это (фактическая реализация варьируется):
namespace FWS
{
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
// [System.Web.Script.Services.ScriptService]
public class FooService : WebService
{
private readonly ILog errorLogger = LogManager.GetLogger("ErrorRollingLogFileAppender");
private readonly IDaoFactory daoFactory = new DaoFactory();
private readonly ISession nhSession = HibernateSessionManager.Instance.GetSession();
}
[WebMethod]
public Bar[] GetFavoriteBars(string someParam, int? onceMore){
return daoFactory.GetBarDao().GetFavoriteBars(someParam, onceMore); //returns a Bar[]
}
}
и мы абстрагируем daobehaviour, или просто используем nhsession напрямую, выставленный как webmethod.
теперь из приложения WinForm все, что вам нужно сделать, это Add a WebReference
что делает все необходимые изменения в конфигурации, но также генерирует все необходимые классы (в этом примере он создаст Bar
class как веб-сервис предоставляет его).
namespace WinFormK
{
public class KForm(): System.Windows.Forms.Form
{
public void Do()
{
var service = new FWS.FooService();
string filePath = "C:\temp\FooData.xml";
Bar[] fetched = service.GetFavoriteBars("yes!", null);
//lets write this to local storage
var frosties = new XmlSerializer(typeof(Bar));
TextReader reader = new StreamReader(filePath);
try
{
var persisted = (T)frosties.Deserialize(reader);
}
catch(InvalidOperationException)
{
//spock, do something
}
finally
{
reader.Close();
reader.Dispose();
}
}
}
}
есть некоторые вещи, которые вы должны принять к сведению:
- вы по существу теряете ленивый материал или, по крайней мере, теряете его в своем приложении winform. Сериализатор XML не может сериализовать прокси, и поэтому вы либо включаете ленивую выборку этих коллекций / свойств, либо используете [Xmlignore] атрибут, который в свою очередь делает то, что он подразумевает при сериализации.
- вы не можете возвращать интерфейсы в сигнатурах WebMethod. Они должны быть конкретными классами. Итак, возвращение
IList<Bar>
придется преобразовать вList<Bar>
или что-то вроде - веб-служба выполняется IIS и отображается из веб-браузера. По умолчанию будут обслуживаться только запросы локального браузера (но это можно изменить), поэтому вы можете проверить свой уровень доступа к данным отдельно от того, что ваш winform делает.
- принимающая сторона (приложение winform) не имеет никаких знаний о NHibernate вообще.
- в приведенном выше примере я сохранил то же имя для dao-методов для веб-методов; пока вы не сохранили методы nhibernate-specific в ваших dao (скажем, как
NHibernate.Criterions.Order
параметр) вы, вероятно, не найдете никаких проблем. На самом деле вы можете иметь столько.asmx
классы в вашем веб-сервисе, как вы хотите, возможно, даже "сопоставьте" их с соответствующими dao (напримерpublic class FooService : WebService
,public class BarService : WebService
,public class CheService : WebService
где каждый соответствует DAO). - вы, вероятно, придется написать какой-то метод опроса между конечными точками для хранения данных.
- данные WebService многословны; чрезвычайно. Желательно, чтобы застегнуть их или что-то перед отправкой их по проводу (и, возможно, зашифровать их, а также)
- приложение win знает только запись конфигурации:
http://server/FWS/FooService.asmx
- веб-службы имеют сеанс по умолчанию отключено. помните, что перед началом сеанса для пользователя данных.
- вам, вероятно, придется написать какую-то аутентификацию для веб-сервиса
в приведенном выше примере я возвращаю
Bar[]
СBar
сопоставляется с nhibernate. Чаще всего это может быть не так, и вам может потребоваться написать вспомогательный классWSBar
где он адаптирует оригиналBar
класс к чему веб-сервис и winform приложение может потреблять. Этот класс на самом деле просто носитель данных. Опять же, это зависит от того, насколько существует интеграция с вашими классами домена и nhibernate, а также насколько muxh усложнили ваши классы: определенные структуры данных не могут быть сериализованы по умолчанию.эта модель может не соответствовать тому, что вы уже сделали с вашим приложением
прежде всего, позволить ненадежным пользователям подключаться к базе данных, как правило, не является хорошей идеей. Так много вещей может пойти не так. Поместите веб-службу между ними.
Если вам абсолютно необходимо это сделать, сделайте так, чтобы это не имело значения, даже если они получат имя пользователя и пароль. Ограничьте их права в базе данных, чтобы они могли выполнять только несколько хранимых процедур со встроенными проверками безопасности.
Что бы вы ни делали, вы не можете дать логин/пароль привилегированный пользователь для ненадежного человека. Это просто напрашивается на неприятности. Независимо от того, насколько хорошо вы пытаетесь скрыть свои учетные данные в зашифрованной строке внутри двоичного файла или чего-то еще, всегда есть способ их найти. Конечно, будет ли кто-то на самом деле это делать, зависит от того, насколько интересны ваши данные, но молчаливая надежда на то, что люди с отладчиками просто оставят вас в покое, не очень хорошая мера безопасности.
Я думаю, что это трудно сделать : это похоже на то, что вы не хотите, чтобы пользователь stackoverflow знал свой пароль. Пользователь всегда может отслеживать свой сетевой трафик и видеть пользователя/пароль (у вас может быть кодировка, но она все равно не будет 100% уверена, что я думаю).
Я думаю, что вы должны добавить веб-сервиса между пользователями и базы данных с уникальным идентификатором для каждого пользователя.
вот почему настольные приложения базы данных сосут. Нет хорошего способа разрезать его. Лучше всего использовать хранимые процедуры или веб-службы. В принципе, еще один слой, который можно заблокировать и контролировать доступ к базе данных.