Многопользовательское приложение с несколькими экземплярами клиентов с использованием общих учетных данных - PullRequest
3 голосов
/ 12 августа 2011

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

Итак, вот что я пытаюсь сделать:

У меня есть мультитенантное приложение с общей структурой для управления мультитенантными аспектами приложения, такими как места хранения данных и т. Д. У каждого арендатора будет «x» количество пользователей, которые могут получить доступ к учетной записи арендатора. Однако у каждого арендатора может быть несколько экземпляров, привязанных к его учетной записи. Например, арендатор может иметь производственный экземпляр, а также тестовый или dev-экземпляр. Каждый экземпляр имеет отношение один к одному с изолированной базой данных. Для меня наиболее разумно, что я буду хранить учетные данные для входа в систему на уровне инфраструктуры в сопоставлении с информацией об арендаторе, а не в каждом отдельном экземпляре, поскольку это увеличит количество имен пользователей и паролей в геометрической прогрессии.

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

Часть, на которую я вешаюсь, такова:

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

Тогда мой вопрос:

Исходя из имеющейся у меня конструкции, какой самый простой способ связать объекты (пользователя и сотрудника) между моделями (каркас, экземпляр)? Что более важно, как мне синхронизировать изменения или модификации данных во всех экземплярах, или я должен даже беспокоиться об этом?

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

Спасибо за ваш опыт!

Brent

Ответы [ 2 ]

11 голосов
/ 15 августа 2011

Похоже, что здесь есть три взаимосвязанные вещи, хотя вопрос вращается вокруг одной:

  1. Как данные хранятся в базе данных?
  2. КакВы гарантируете, что каждый пользователь имеет доступ только к тем экземплярам, ​​на которые у него есть права?
  3. Как сопоставить данные с объектами для использования в коде?

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

Как данные хранятся в базе данных?

Поскольку у вас есть одна база данных на экземпляр клиентаприложения (каждая «среда» - производство, тестирование и т. д. будет экземпляром арендатора), и у вас есть данные, относящиеся ко всем из них, я бы также сохранил «общие» данные в отдельной базе данных.

Давайте назовем эту базу данных базой данных SystemConfiguration.При этом у вас будет:

  • Список всех клиентов в системе.
  • Список глобальных параметров конфигурации каждого экземпляра (например, имя базы данных, конечные точки службы и т. Д.).), каждый экземпляр сопоставлен с арендатором.
  • Список всех пользователей в системе, каждый из которых сопоставлен с арендатором (при условии, что один пользователь не может пересекать арендаторов ... что может быть сложным, ноне невозможно).
  • Отображение пользователей на идентификаторы каждого экземпляра, к которому имеет доступ каждый пользователь.

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

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

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

Как вы гарантируете, что каждый пользователь имеет доступ только к тем экземплярам, ​​на которые у него есть права?

Я думаю, что аутентификация / авторизация на основе утверждений значительно упростила бы эту проблему.Если вы не знакомы с утверждениями, идея заключается в том, что вместо статического списка «ролей», в которых находится пользователь, у вас есть словарь пар имя / значение, связанных с каждым пользователем.Словарь является «набором требований» пользователя, а каждая пара «имя / значение» является «утверждением».Преимущество перед ролями заключается в том, что значение может быть любым, включая список.

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

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

Возвращение его в хранилище данных - генерация набора заявок из этой базы данных SystemConfiguration будет тривиальным запросом.

Подробнее об идентификации на основе утверждений и о том, как использовать Windows Identity Foundation для работы в вашем приложении, см. Программирование Windows Identity Foundation , автор Vittorio Bertocci .Это хорошая книга ... и почти единственная книга по WIF.

Как вы сопоставляете данные с объектами для использования в коде?

На этомДело в том, что речь идет скорее о представлении данных из вашего кода, чем о структуре хранилища данных.Если вы хотите, чтобы объект Арендатора имел IEnumerable в нем, это все просто возражает с ORM по вашему выбору.

Я мог бы предложить обернуть операции, по крайней мере, вокруг базы данных SystemConfiguration, с контрактом на обслуживание, поэтому, если вы измените данные под ним, вы можете настроить ORM на уровне обслуживания, а не на потребляющем коде. Интерфейсы!

В любом случае, суть в том, что я не буду пытаться основывать хранилище данных на том, как вы потребляете данные.

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

Это может быть еще одна причина, чтобы обернуть вещи в услуги. Например, если у вас есть служба «UserSettings», ваш контракт может запрашивать идентификатор экземпляра клиента и идентификатор пользователя и возвращать список настроек. За кулисами служба может запрашивать данные из SystemConfiguration, сопоставлять их с соответствующей базой данных экземпляра и возвращать объединенный набор данных - все прозрачно для вызывающего кода. С другой стороны, вы не получаете того приятного метода «Update ()», который дают вам некоторые ORM, когда вы просто изменяете значения в объектах и ​​хотите зафиксировать изменения. Это компромисс между тем, хотите ли вы привести ORM в соответствие, чтобы это произошло.

0 голосов
/ 12 августа 2011

Переписать:

[Похоже, мой первоначальный ответ был нецелевым, и в любом случае это примерно то, что у вас есть.Итак ...]

как синхронизировать изменения или модификации данных во всех экземплярах, или мне даже об этом беспокоиться?

Есть ли у вас требование, которое требует от них синхронизации или какого-либо другого драйвера?Если нет ... Предполагая, что вы делаете, вам нужно решить, с чем вы собираетесь синхронизироваться;что является единственным источником истины.

A Публикация / подписка или Наблюдатель подход типа может быть то, что вы ищете.

  • Экземпляры "публикуют" изменения в центральной системе, которые другие экземпляры извлекают либо в течение своего обычного жизненного цикла, либо в режиме ad-hoc на основании события / уведомления, выпущенного центральной системой.
  • Или аналогичный, но децентрализованный подход, при котором изменения передаются сразу всем заинтересованным сторонам (думаю, гораздо сложнее и с новым набором проблем).
...