Аутентификация, авторизация, управление пользователями и ролями и общая безопасность в .NET

StackOverflow https://stackoverflow.com/questions/1222974

Вопрос

Мне нужно знать, как приступить к реализации общей безопасности для приложения на 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 списка групп, членом которых является вошедший в систему пользователь.Затем проверьте наличие соответствующих названий групп и создайте свой пользовательский интерфейс на основе членства таким образом.

Таким образом, мои приложения работают следующим образом:

  1. При запуске приложения учетные данные зависят от вошедшего в систему пользователя, это основной аспект аутентификации (т.е.они могут войти в систему, следовательно, они существуют)
  2. Я получаю все группы Для удостоверения Windows, о котором идет речь
  3. Я проверяю наличие стандартной группы ПОЛЬЗОВАТЕЛЕЙ - если эта группа не существует для рассматриваемого удостоверения Windows, то это ошибка аутентификации
  4. Я проверяю наличие группы пользователей ADMIN - поскольку она существует в группах пользователей, я изменяю пользовательский интерфейс, чтобы разрешить доступ к компонентам администрирования
  5. Отображение пользовательского интерфейса

Затем у меня есть либо ОСНОВНОЙ объект с определенными правами / 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 членства в соответствии с вашими потребностями.

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

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

http://www.visual-guard.com/EN/net-powerbuilder-application-security-authentication-permission-access-control-rbac-articles/dotnet-security-article-ressources/role-based-access-control-source_soforum.html

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top