Подтвердить что ты не робот

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

Мне нужно знать, как реализовать общую безопасность для приложения на С#. Какие варианты у меня есть в этом отношении? Я бы предпочел использовать существующий каркас, если он отвечает моим потребностям - я не хочу заново изобретать колесо.

Мои требования следующие:

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

Я ищу бесплатную инфраструктуру/библиотеку с открытым исходным кодом, которая была проверена временем и используется сообществом .Net.

Мое приложение использует клиент-серверный подход, когда сервер работает как служба Windows, подключаясь к базе данных SQL Server. Связь между клиентом и сервером будет осуществляться через WCF.

Еще одна важная вещь заключается в том, что мне нужно иметь возможность назначать определенные права пользователей или ролей для просмотра/обновления/удаления конкретной сущности, будь то Клиент, Продукт или т.д. Например, Джек может просматривать определенную 3 из 10 клиенты, но только обновить данные клиентов Microsoft, Yahoo и Google, и могут только удалить Yahoo.

4b9b3361

Ответ 1

Для крупнозернистой безопасности вы можете найти полезный главный код; пользовательский объект (и их роли) управляется в .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...");
    }
}

Однако это не помогает с мелким доступом (т.е. "Fred может получить доступ к клиенту 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;
}

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

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
    }
}

Ответ 2

Посмотрите Поставщики членства ASP.NET. Я не думаю, что вне коробки SQLMembershipProvider будет работать в вашем случае, но достаточно легко запустить своего собственного провайдера.

Ответ 3

мой ответ, вероятно, зависит от ответа на этот вопрос: Это приложение Enterprise, которое живет в сети с Active Directory?

ЕСЛИ ответ да, то это шаги, которые я бы предоставил:

1) Создайте глобальные группы для своего приложения, в моем случае у меня была группа APPUSER и группа APPADMIN.

2) Доступ к вашему SQL Server можно получить в режиме MIXED AUTHENTICATION, а затем назначьте группы APPUSER в качестве СУБД SQL SERVER в вашу базу данных с соответствующими правами CRUD на ваши DB и убедитесь, что что вы подключаетесь к SQL SERVER с Trusted Connection = True в строке подключения.

На этом этапе ваше хранилище AD будет отвечать за аутентификацию. Поскольку вы получаете доступ к приложению через TRUSTED CONNECTION, он передает личность любой учетной записи приложения на SQL Server.

Теперь, для АВТОРИЗАЦИИ (т.е. сообщая вашему приложению, что разрешен зарегистрированный пользователь), это простой вопрос запроса AD для списка групп, членом которого является зарегистрированный пользователь. Затем проверьте подходящие имена групп и создайте свой пользовательский интерфейс на основе членства таким образом.

Так работают мои приложения:

  • Запуск приложения, учетные данные основаны на вошедшем в систему пользователе, это основной аспект аутентификации (т.е. они могут регистрироваться, поэтому они существуют).
  • Я получаю все группы для рассматриваемой Windows Identity
  • Я проверяю стандартную группу USER - если эта группа не существует для рассматриваемой Windows Identity, тогда аутентификация FAIL
  • Я проверяю группу пользователей ADMIN. Если это существует в группах пользователей, я изменяю пользовательский интерфейс, чтобы разрешить доступ к компонентам администрирования.
  • Отобразить пользовательский интерфейс

Затем у меня есть либо объект PRINCIPLE с определенными правами /etc на нем, либо я использую GLOBAL-переменные, к которым я могу получить доступ, чтобы определить соответствующий пользовательский интерфейс при создании моих форм (т.е. если мой пользователь не является членом группы ADMIN, тогда я бы спрятал все кнопки DELETE).

Почему я предлагаю это?

Это вопрос развертывания.

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

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

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

Ответ 5

WCF имеет богатую функциональность, связанную с безопасностью, обеспечивает как авторизацию, так и аутентификацию. Подробнее здесь: http://msdn.microsoft.com/en-us/library/ms735093.aspx

Ответ 6

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

Для аутентификации больший вопрос логичен. Или, есть ли логическое место для этих пользователей для жизни, будь то локально для приложения, в Active Directory, в другом хранилище LDAP или даже в каком-либо другом приложении. Именно там, где это довольно немаловажно, нам просто нужно иметь возможность прочно идентифицировать пользователей и, предпочтительно, сделать эту задачу чужой проблемой. Конец дня вам действительно нужен уникальный идентификатор и комфорт, который Боб из Учетного счета фактически является Бобом из Бухгалтерии.

Авторизация - это более интересная часть проблемы. Я думаю, если это действительно тонко, вы действительно хотите управлять этим целиком в своем приложении, независимо от того, откуда пришли пользователи. Марк Гравелл действительно ударил по хорошему способу моделирования хотя бы некоторых из них - использовать некоторые пользовательские реализации IPrincipal и PrincipalPermission для управления вещами - это очень простой способ начать работу. Помимо этого вы можете использовать методы, такие как этот, чтобы сделать более сложные решения авторизации довольно чистым способом.

Ответ 7

Я бы использовал термин "RBAC" (система контроля доступа на основе ролей) в качестве решения всех ваших требований.

Я бы не стал вдаваться в подробности для объяснения "RBAC" здесь, я бы кратко описал его как:

Он в основном содержит 3 функции.

1) Аутентификация - подтверждает личность пользователя. Обычно это делается через учетные записи пользователей и пароли или учетные данные.

2) Авторизация - определяет, что пользователь может делать и чего не может делать в приложении. Ex. "Изменение заказа разрешено, но" создание нового заказа не допускается.

3) Аудит действий пользователя над приложениями. - Он отслеживает действия пользователей над приложениями, а также кто и кому предоставил доступ?

Вы можете проверить RBAC на вики здесь.

https://en.wikipedia.org/wiki/Role-based_access_control

Теперь, что касается ответа на ваши требования - одно из возможных решений - расширить членство в ASP.NET в соответствии с вашими потребностями.

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

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

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