2017-02-07 2 views
0

У меня есть класс, который отслеживает изменения свойствБезопасность/Проверка на с изменением # собственности N-Tier

public class Property 
     { 
      object _OriginalValue; 
      object _ProposedValue; 
      DateTime _ProposedDateTime; 
      List<Property> _History = new List<Property>(); 
      public object OriginalValue 
      { 
       get 
       { 
        return _OriginalValue; 
       } 

       set 
       { 
        _OriginalValue = value; 
       } 
      } 
      public object ProposedValue 
      { 
       get 
       { 
        return _ProposedValue; 
       } 

       set 
       { 
        _ProposedDateTime = DateTime.Now; 
        _ProposedValue = value; 
       } 
      } 
      public bool IsDirty 
      { 
       get 
       { 

        if (OriginalValue != ProposedValue) 
        { 
         return true; 
        } 
        else 
        { 
         return false; 
        } 
       } 
      } 
     } 

Это свойство может быть использовано классами как

public class Customer 
     { 
      protected Property _FirstName = new Property(); 
      public string FirstName 
      { 
       get 
       { 
        return (string)_FirstName.ProposedValue; 
       } 

       set 
       { 
        _FirstName.ProposedValue = value; 
       } 
      } 

      public object GetOriginalValue(Property Property) 
      { 
       return Property.OriginalValue; 
      } 

     } 

Вопрос заключается в том, является существует ли способ обеспечить первоначальное значение при передаче этого клиенту в архитектуре N-уровня?

Когда клиент передает Клиенту обратно в Границу обслуживания - по умолчанию вы не можете доверять клиенту. Вам нужно либо перезагрузить исходные значения из базы данных, либо подтвердить, что исходные значения неактивны. Конечно, я предполагаю, что мы будем использовать бизнес-логику, основанную на текущих значениях в клиенте, чтобы отклонить или разрешить операцию обновления.

Пример:

Пользователь вставляет запись с именем Боба.

Пользователь извлекает запись с именем Bob и меняет имя на Ted. Исходным значением является Боб, предлагаемое значение - Ted.

Пользователь отправляет Заказчика в службу обновления Клиента.

Все хорошо.

* В настоящее время бизнес-правило закодировано в службу, в которой говорится, что если имя клиента Ted - разрешить повторному обновлению исключить исключение «невозможно обновить». *

Пользователь извлекает запись с именем Ted. Пользователь меняет имя на Darren. Пользователь меняет имя обратно на Ted - исключает систему. Пользователь выбирает Тед. Пользователь читает и использует инструмент для изменения свойства OriginalPropertyValue на клиенте. Сервер не обновляет исходную базу данных из базы данных и просто считывает исходный валид, исходящий от клиента.

Пользователь обходит бизнес-правило.

+0

Вы можете посмотреть на [TrackerDog] (http://matiasfidemraizer.com/trackerdog) ([GitHub хранилище] (https://github.com/mfidemraizer/trackerdog)). Я чувствую, что это сильно очистит ваш код :) –

+0

Совершенно без темы. Предоставленный код - это просто продемонстрировать идею и не является фактическим производственным кодом. Благодарю. – Watson

+0

Не стесняйтесь публиковать решение, используя TrackerDog в качестве примера. Внесите изменения на клиенте, передайте изменения на сервер и подтвердите, что клиент не изменил никаких исходных значений, установленных базой данных, или не имеет способа вставить текущие значения из базы данных в исходные значения. – Watson

ответ

2

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

Я полагаю, вы уже применяете какую-то оптимистичную или пессимистическую блокировку своих данных ...

Об реальной озабоченности, вероятно, вам нужно sign вашего исходного значения, и всякий раз, когда вы собираетесь хранить эти объекты обратно в базе данных, ваш слой приложения должен проверить, что исходного значение не было подделаны (из Википедии):

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

+0

Матиас, прежде чем писать этот пост, я прочитал два способа справиться с этим: отмените значения на сервере или, конечно же, примените некоторую технику, чтобы сделать ее доказательством. То, что я действительно получаю после, - это производительность - стоит ли тратить больше денег на базу данных или стоит больше подписать исходные значения. Некоторые проверки параллелизма блокировали бы этот тип атаки (добавляя, где предложение к исходным значениям {where name = @ Name}), поскольку это игнорирует обновление, если у вас не было исходных значений. – Watson

+0

@Watson Я бы пошел на подписание. Это не сложный процесс, а современный процессор ультрамощный :) Я уверен, что при запросе базы данных есть задержки, общая стоимость, мы должны сделать тест производительности ... Это не то же самое, что и для SQL Server, чем для Redis! –

Смежные вопросы