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

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

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

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

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

мое приложение использует подход клиент / сервер, при этом сервер работает как служба windows, подключаясь к базе данных SQL Server. Связь между клиентом и сервером будет осуществляться через WCF.

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

7 ответов


для крупнозернистой безопасности может оказаться полезным встроенный основной код; объект пользователя (и их роли) управляются в .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 ' S поставщики членства. Я не думаю, что из коробки SQLMembershipProvider будет работать в вашем случае, но достаточно легко свернуть собственного поставщика.


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

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

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

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

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

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

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

  1. запуск приложения, учетные данные основаны на зарегистрированном пользователе, это основной аспект аутентификация (т. е. они могут войти в систему, поэтому они существуют)
  2. я получаю все группы для идентификатора Windows в вопросе
  3. я проверяю стандартную группу пользователей - если эта группа не существует для удостоверения Windows, о котором идет речь, то это ошибка аутентификации
  4. я проверяю группу пользователей ADMIN -- с этим, существующим в группах пользователя, я изменяю пользовательский интерфейс, чтобы разрешить доступ к компонентам администрирования
  5. отобразить UI

затем у меня есть либо объект принципа с определенными правами/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 членство в соответствии с потребностями.

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

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

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