Аутентификация, авторизация, управление пользователями и ролями и общая безопасность в .NET
-
11-07-2019 - |
Вопрос
Мне нужно знать, как приступить к реализации общей безопасности для приложения на C #.Какие варианты у меня есть в этом отношении?Я бы предпочел использовать существующий фреймворк, если он отвечает моим потребностям - я не хочу заново изобретать колесо.
Мои требования заключаются в следующем:
- обычная аутентификация по имени пользователя/паролю
- управление пользователями - назначение разрешений пользователям
- управление ролями - назначение пользователей ролям, назначение разрешений ролям
- авторизация пользователей на основе их имени пользователя и роли
Я ищу бесплатную платформу / библиотеку с открытым исходным кодом, которая была проверена временем и использовалась .Сетевое сообщество.
Мое приложение использует клиент-серверный подход, при котором сервер работает как служба Windows, подключаясь к базе данных SQL Server.Связь между клиентом и сервером будет осуществляться через WCF.
Еще одна важная вещь заключается в том, что мне нужно иметь возможность назначать определенным пользователям или ролям разрешения на просмотр / обновление / Удаление определенного объекта, будь то Клиент, Продукт и т.д.Например, дляДжек может просматривать определенных 3 из 10 клиентов, но обновляет сведения только о клиентах Microsoft, Yahoo и Google и может удалять только Yahoo.
Решение
Для обеспечения крупномасштабной безопасности вам может оказаться полезным встроенный основной код;пользовательский объект (и их роли) управляются в .NET "принципалом", но с пользой для себя среда выполнения может обеспечить это.
Реализация принципала может быть определена реализацией, и обычно вы можете ввести свой собственный; например, в WCF.
Чтобы увидеть, как среда выполнения обеспечивает грубый доступ (т.е.который функциональность может быть доступен, но не ограничен тем, к какому конкретному данные):
static class Roles {
public const string Administrator = "ADMIN";
}
static class Program {
static void Main() {
Thread.CurrentPrincipal = new GenericPrincipal(
new GenericIdentity("Fred"), new string[] { Roles.Administrator });
DeleteDatabase(); // fine
Thread.CurrentPrincipal = new GenericPrincipal(
new GenericIdentity("Barney"), new string[] { });
DeleteDatabase(); // boom
}
[PrincipalPermission(SecurityAction.Demand, Role = Roles.Administrator)]
public static void DeleteDatabase()
{
Console.WriteLine(
Thread.CurrentPrincipal.Identity.Name + " has deleted the database...");
}
}
Однако это не помогает с детализированным доступом (т.е."Фред может получить доступ к клиенту A, но не к клиенту B").
Дополнительный;Конечно, для мелкозернистого вы можете просто проверить требуемые роли во время выполнения, проверив IsInRole
о главном:
static void EnforceRole(string role)
{
if (string.IsNullOrEmpty(role)) { return; } // assume anon OK
IPrincipal principal = Thread.CurrentPrincipal;
if (principal == null || !principal.IsInRole(role))
{
throw new SecurityException("Access denied to role: " + role);
}
}
public static User GetUser(string id)
{
User user = Repository.GetUser(id);
EnforceRole(user.AccessRole);
return user;
}
Вы также можете написать свои собственные объекты principal / identity, которые выполняют отложенные тесты / кэширование ролей, вместо того, чтобы заранее знать их все:
class CustomPrincipal : IPrincipal, IIdentity
{
private string cn;
public CustomPrincipal(string cn)
{
if (string.IsNullOrEmpty(cn)) throw new ArgumentNullException("cn");
this.cn = cn;
}
// perhaps not ideal, but serves as an example
readonly Dictionary<string, bool> roleCache =
new Dictionary<string, bool>();
public override string ToString() { return cn; }
bool IIdentity.IsAuthenticated { get { return true; } }
string IIdentity.AuthenticationType { get { return "iris scan"; } }
string IIdentity.Name { get { return cn; } }
IIdentity IPrincipal.Identity { get { return this; } }
bool IPrincipal.IsInRole(string role)
{
if (string.IsNullOrEmpty(role)) return true; // assume anon OK
lock (roleCache)
{
bool value;
if (!roleCache.TryGetValue(role, out value)) {
value = RoleHasAccess(cn, role);
roleCache.Add(role, value);
}
return value;
}
}
private static bool RoleHasAccess(string cn, string role)
{
//TODO: talk to your own security store
}
}
Другие советы
Загляни в ASP.NET Поставщики членства в.Я не думаю, что готовый SqlMembershipProvider будет работать в вашем случае, но его достаточно легко подключить к вашему собственному провайдеру.
мой ответ, вероятно, зависит от ответа на этот вопрос: Является ли это корпоративным приложением, которое работает в сети с Active Directory?
ЕСЛИ ответ "да", то это те шаги, которые я бы предложил:
1) Создайте глобальные группы для вашего приложения, в моем случае у меня была группа APPUSER и группа APPADMIN.
2) Обеспечьте доступ к вашему SQL Server в режиме смешанной аутентификации, а затем назначьте вашу группу (группы) APPUSER в качестве ВХОДА SQL SERVER в вашу базу данных с соответствующими правами CRUD для вашей базы (ов) данных и убедитесь, что вы обращаетесь к SQL SERVER с Доверенное соединение = True в вашей строке подключения.
На этом этапе за аутентификацию будет отвечать ваш рекламный магазин.Поскольку вы получаете доступ к приложению через ДОВЕРЕННОЕ СОЕДИНЕНИЕ, оно передаст SQL Server идентификатор любой учетной записи, под управлением которой запущено приложение.
Теперь, для АВТОРИЗАЦИИ (т.е.сообщая вашему приложению, что разрешено делать вошедшему в систему пользователю) это простой вопрос запроса AD списка групп, членом которых является вошедший в систему пользователь.Затем проверьте наличие соответствующих названий групп и создайте свой пользовательский интерфейс на основе членства таким образом.
Таким образом, мои приложения работают следующим образом:
- При запуске приложения учетные данные зависят от вошедшего в систему пользователя, это основной аспект аутентификации (т.е.они могут войти в систему, следовательно, они существуют)
- Я получаю все группы Для удостоверения Windows, о котором идет речь
- Я проверяю наличие стандартной группы ПОЛЬЗОВАТЕЛЕЙ - если эта группа не существует для рассматриваемого удостоверения Windows, то это ошибка аутентификации
- Я проверяю наличие группы пользователей ADMIN - поскольку она существует в группах пользователей, я изменяю пользовательский интерфейс, чтобы разрешить доступ к компонентам администрирования
- Отображение пользовательского интерфейса
Затем у меня есть либо ОСНОВНОЙ объект с определенными правами / etc на него, либо я использую ГЛОБАЛЬНЫЕ переменные, к которым я могу получить доступ, чтобы определить соответствующий пользовательский интерфейс при создании моих форм (т. Е.если мой пользователь не является членом группы администраторов, то я бы скрыл все кнопки УДАЛЕНИЯ).
Почему я это предлагаю?
Это вопрос развертывания.
По моему опыту, большинство корпоративных приложений развертываются сетевыми инженерами, а не программистами - поэтому возложение ответственности за аутентификацию / авторизацию на AD имеет смысл, поскольку именно туда обращаются сетевые специалисты, когда вы обсуждаете аутентификацию / авторизацию.
Кроме того, во время создания новых пользователей для сети сетевой инженер (или кто-либо другой, ответственный за создание новых пользователей сети) более склонен помнить о необходимости выполнения групповых назначений, пока они находятся В AD, чем о том факте, что им приходится заходить в дюжину приложений, чтобы проанализировать назначения авторизации.
Это помогает справиться с лабиринтом разрешений и прав, которые необходимо предоставить новым сотрудникам или отказать тем, кто покидает компанию, и поддерживает аутентификацию и авторизацию в центральном хранилище, где оно принадлежит (т.е.в AD @ на уровне контроллера домена).
Я бы взглянул на что-то вроде CSLA.net: Экспертные бизнес-объекты C # 2008
Он должен обеспечить все, что вам требуется.
WCF обладает богатыми функциональными возможностями, связанными с безопасностью, обеспечивающими как авторизацию, так и аутентификацию.Подробнее здесь:http://msdn.microsoft.com/en-us/library/ms735093.aspx
Я думаю, что здесь вы сталкиваетесь с несколькими отдельными проблемами - не случайно большинство систем безопасности разделяют аутентификацию и авторизацию.
Что касается аутентификации, то более важный вопрос заключается в логистике.Или есть ли логичное место для проживания этих пользователей, будь то локально в приложении, в Active Directory, в каком-либо другом хранилище LDAP или даже в каком-то другом приложении.Где именно, совершенно несущественно - нам просто нужно быть в состоянии точно идентифицировать пользователей и, желательно, сделать эту задачу проблемой кого-то другого.В конце концов, вам действительно нужен просто уникальный идентификатор и уверенность в том, что Боб из Бухгалтерии на самом деле Боб из Бухгалтерии.
Авторизация - это более интересная часть проблемы здесь.Я думаю, если это действительно детализировано, вы действительно хотите полностью управлять этим в своем приложении, независимо от того, откуда приходят пользователи.Марк Гравелл действительно нашел хороший способ смоделировать хотя бы часть этого - использовать какую-нибудь пользовательскую реализацию IPrincipal и PrincipalPermission для управления вещами - это очень простой способ начать.Помимо этого, вы можете использовать такие методы, как этот принимать более сложные решения об авторизации довольно простым способом.
Я бы использовал термин "RBAC" (система контроля доступа на основе ролей) в качестве решения для всех ваших требований.
Я бы не стал вдаваться в подробности, объясняя здесь "RBAC", скорее я бы кратко описал его как:
В основном он содержит 3 функции.
1) Аутентификация - она подтверждает личность пользователя.Обычно это делается с помощью учетных записей пользователей и паролей или учетных данных.
2) Авторизация - она определяет, что пользователь может делать и чего не может делать в приложении.Бывший.‘Изменение заказа’ разрешено, но ‘создание нового заказа’ запрещено.
3) Аудит действий пользователя над приложениями.- Он отслеживает действия пользователя в приложениях, а также кто каким пользователям предоставил доступ?
вы можете проверить RBAC на wiki здесь.
https://en.wikipedia.org/wiki/Role-based_access_control
Теперь, что касается ответа на ваши требования - одним из возможных решений является продление ASP.NET членства в соответствии с вашими потребностями.
А что касается какого-нибудь готового к использованию фреймворка, я бы порекомендовал Визуальный предохранитель для которого я работаю, вы должны проверить это, он очень легко выполняет все, что вам нужно, и, что наиболее важно, он управляет всеми вашими пользователями, ролями, разрешениями и приложениями через консоль центрального администрирования, а для определения разрешений администраторам не требуются знания разработчика, т. е. он / она может создавать ограничения на действия через пользовательский интерфейс.
вы также можете ознакомиться с этой статьей, чтобы получить больше информации о системе, основанной на разрешениях и ролях.