none
Разграничение доступа: Server Login, Database User, Roles или всё вместе? RRS feed

  • Вопрос

  • Здравствуйте!
    Возник вопрос по проектированию системы безопасности БД на сервере MS SQL 2008 R2.
    Есть система по учёту успеваемости студентов - необходимо гарантировать соблюдение прав доступа к объектам БД.
    Есть различные роли пользователей (их немного), и есть сами пользователи (а их несколько сотен).
    Клиентское приложение работает с БД при помощи Entity Framework.
    Как себе представлял систему авторизации я:
    • Программа подключается к БД, используя один общий Server Login (цели: не захламлять общее для СУБД пространство и держать всё касательно конкретных пользователей внутри БД)
    • При успешном подключении программе даются права только на одну процедуру - Authenticate(login, pass), которая проверит наличие пользователя в БД и изменит контекст подключения (права доступа) в соответствии с ролями (а их может быть несколько) вошедшего пользователя
    Скорее всего, я просто не до конца разобрался, но столкнулся с проблемами:
    • Использование Database Users (EXEC AS) не требует ввода пользовательских паролей
    • SetUser - вообще предназначен для другого
    Так что я не нашёл, как, используя инструмент DB Users, решить поставленную задачу.
    В итоге получилось пока сделать вот как (благо, есть SQL Server SMO):
    • Создать для каждого пользователя свой Server Login (ха, зрелище #mce_temp_url# то ещё)
    • Создать для каждого пользователя свой Database User, привязанный к логину
    • Добавить каждому пользователю нужные Database Roles
    С одной стороны, при таком решении вход на сервер осуществляется сразу со своими правами доступа.
    Но с другой стороны:
    • Совершенно не радует необходимость изменения списка Server Logins при добавлении/изменении пользователей (что может стать серьёзной дыркой в безопасности при неаккуратной реализации, дав возможность авторизованному пользователю создать другого пользователя с более высокими правами и получить через него доступ к системе)
    • При переносе БД потеряются все Server Logins, т.к. не хранятся внутри БД - нужно будет пересоздавать
    • Такое количество всяких пользователей, вероятно, негативно скажется на производительности сервера, в отличие от хранения их в таблицах самой БД и простых проверок через запросы 
    Также я присматривался и к Application Roles. Но в случае с ними я не нашёл, как предоставлять совокупные права пользователю, "играющему" сразу несколько ролей. "Приложение"-то одно для всех, а права могут быть комплексными.
    Подскажите, пожалуйса, в какую сторону думать в такой ситуации?

Ответы

  • Лучше сделать не напрямую работу с базой, а через WCF сервисы, которые будут авторизовать пользователя и запрещать выполнять некоторые функции согласно роли. Минус - большинство фишек EF останутся на сервисе, но зато будет полное разделение логики.
    • Помечено в качестве ответа Abolmasov Dmitry 26 мая 2011 г. 18:07

Все ответы

  • Лучше сделать не напрямую работу с базой, а через WCF сервисы, которые будут авторизовать пользователя и запрещать выполнять некоторые функции согласно роли. Минус - большинство фишек EF останутся на сервисе, но зато будет полное разделение логики.
    • Помечено в качестве ответа Abolmasov Dmitry 26 мая 2011 г. 18:07
  • Антон, большое спасибо за ответ!

    В принципе, это хороший вариант. Но дело в том, что само приложение уже практически реализовано, оно всё пронизано EF-классами и работой с их экземплярами. Я в любом случае буду разбираться в ближайшее время с WCF Services (т.к. пока работал только с их Web-товарищем), но в этом проекте хотелось бы какого-то "простого" решения. Не хочется переписывать весь код клиента (а он получился весьма пухленьким). Тем более, что SQL Server-то, безусловно, позволяет в несколько кликов настроить разграничение доступа. Главное - понять, как этой возможностью грамотно воспользоваться (что у меня пока и не получается).

    То есть глобально мне идея WCF очень нравится и она явно выигрышна. Но хотелось бы найти "короткую дорожку". В данном случае я даже готов согласиться на бардак в списке Server Logins, чтобы не переписывать всю логику объектов на клиенте.

  • Ещё такой вариант: в базе сделать столько юзеров сколько ролей и ходить только под ними в неё. Сделать отдельно сервис Login, который при авторизации отдельного пользователя по его роли будет возвращать строку подключения к базе с нужным пользователем с нужными правами.

    Минус: нужно думать о том как эту строку секьюрно передать приложению, чтобы её нельзя было перехватить. Возможны ещё какие-то подводные камни, которые на первый взгляд не видны.

  • По-моему, в этом случае не получится реализовать возможность наличия множественных ролей (и предоставления совокопности всех прав) у одного пользователя. К примеру, есть у нас Преподаватель, который заодно Сотрудник, а не дай бог ещё и Студент на втором высшем и Отец какого-нибудь другого студента :) Необходимо было бы тогда создавать отдельного Database User-а под каждое сочетание ролей.

    P.S. на тему секьюрити, кстати, мне очень понравилось, как в новом SQL сделано: с TDE и SSL-шифрованием канала все необходимые изменения состояли в паре команд на сервере и добавлении "Encrypt=true;" к строке подключения на клиенте.

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