Лучшие практики для ролей и утверждений в удостоверении ASP.NET

98

Я совершенно не знаком с использованием claimsin ASP.NETIdentityи хочу получить представление о передовых методах использования Roles and/or Claims.

После всего этого чтения у меня остались вопросы вроде ...

В: Мы больше не используем роли?
В: Если да, то почему все еще предлагаются роли?
В: Должны ли мы использовать только претензии?
В: Следует ли нам использовать роли и утверждения вместе?

Моя первоначальная мысль состоит в том, что мы «должны» использовать их вместе. Я вижу Claimsподкатегории тех, кого Rolesони поддерживают.

НАПРИМЕР:
Роль:
Заявления о бухгалтерском учете : CanUpdateLedger, CanOnlyReadLedger, CanDeleteFromLedger

В: Предполагается ли, что они будут взаимоисключающими?
В: Или лучше пойти ТОЛЬКО на претензии и "полностью квалифицировать" свои претензии?
В: Итак, каковы здесь лучшие практики?

ПРИМЕР: Совместное использование ролей и утверждений.
Конечно, вам придется написать собственную логику атрибутов для этого ...

[Authorize(Roles="Accounting")]
[ClaimAuthorize(Permission="CanUpdateLedger")]
public ActionResult CreateAsset(Asset entity)
{
    // Do stuff here

    return View();
}

ПРИМЕР: ваши претензии полностью соответствуют требованиям

[ClaimAuthorize(Permission="Accounting.Ledger.CanUpdate")]
public ActionResult CreateAsset(Asset entity)
{
    // Do stuff here

    return View();
}
Заключенный ZERO
источник
1
Итак, теперь я столкнулся с той же проблемой, как вы ее решаете и как вы можете переназначить разрешение в приложении?
Loai

Ответы:

78

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

Напротив, утверждение основано не на группе, а на идентичности.

из документации Microsoft :

При создании удостоверения ему может быть назначено одно или несколько утверждений, выданных доверенной стороной. Утверждение - это пара "имя-значение", которая представляет собой предмет, а не то, что он может делать.

Проверка безопасности может позже определить право доступа к ресурсу на основе значения одного или нескольких утверждений.

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

Претензии
источник
7
Я не верю, что это совсем правильно. Я считаю, что претензии указывают на личность, а не на авторизацию. То, что им разрешено делать, управляется отдельно. То есть, у них может быть заявление, в котором дата рождения указывает на то, что им больше 18 лет. Это утверждение будет передано диспетчеру авторизации, который может содержать правило, которое гласит: «Если им больше 18 лет, они могут редактировать ресурс X», но в самом заявлении не указано, что они могут / не могут делать или к чему имеют доступ. То же самое касается ролей и других требований. Заявления указывают на то, кто вы есть, и используются для определения того, что вы можете делать, но они не говорят вам напрямую
ChrisC
Вспомогательная документация для @ChrisC взята из авторизации Microsoft на основе утверждений в ASP.NET Core : «Утверждение - это пара значений имени, которая представляет собой субъект, а не то, что субъект может делать».
DrGriff
@DrGriff Спасибо за ссылку; Некоторое время я задавался вопросом о точности описания, которое я дал; Думаю, теперь я уточнил ответ на основе этой ссылки.
Заявлено
31

Как прекрасно объяснил @Claies, утверждения могут быть более наглядными и представляют собой глубокую роль. Я думаю о них как о ваших ролях. У меня есть идентификатор спортзала, поэтому я принадлежу к роли участника. Я также хожу на уроки кикбоксинга, поэтому у меня есть претензия на кикбоксинг. Моему заявлению потребуется объявление новой роли, чтобы соответствовать моим правам членства. Вместо этого у меня есть идентификаторы для каждого класса группы, к которому я принадлежу, вместо множества новых типов членства. Поэтому мне больше подходят претензии.

Есть отличное видео с объяснением Барри Дорранса, в котором говорится о преимуществах использования требований перед ролями. Он также утверждает, что роли все еще находятся в .NET для обратной совместимости. Видео очень информативно о том, как работают утверждения, роли, политики, авторизация и аутентификация.

Вы можете найти его здесь: Авторизация ASP.NET Core с Барром Доррансом

Джонатан Рамос
источник
8

В моем текущем приложении MVC, использующем различные методы аутентификации и авторизации на протяжении десятилетий, используется следующая методология.

Претензии используются для всей авторизации. Пользователям назначается одна роль (возможно несколько ролей, но мне это не нужно) - подробнее ниже.

Как обычно, используется класс атрибута ClaimsAuthorize. Поскольку большинство действий контроллера являются CRUD, у меня есть процедура в генерации базы данных с первым кодом, которая повторяет все действия контроллера и создает типы утверждений для каждого атрибута действия контроллера Read / Edit / Create / Delete. Например, от,

[ClaimsAuthorize("SomeController", "Edit")]
[HttpPost]

Для использования в представлении MVC базовый класс контроллера представляет элементы пакета представления

        protected override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            // get user claims
            var user = filterContext.HttpContext.User as System.Security.Claims.ClaimsPrincipal;

            if (user != null)
            {
                // Get all user claims on this controller. In this controler base class, [this] still gets the descendant instance type, hence name
                List<Claim> claims = user.Claims.Where(c => c.Type == this.GetType().Name).ToList();

                // set Viewbag with default authorisations on this controller
                ViewBag.ClaimRead = claims.Any(c => c.Value == "Read");
                ViewBag.ClaimEdit = claims.Any(c => c.Value == "Edit");
                ViewBag.ClaimCreate = claims.Any(c => c.Value == "Create");
                ViewBag.ClaimDelete = claims.Any(c => c.Value == "Delete");
            }

            base.OnActionExecuting(filterContext);
        }

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

bool UserHasSpecificClaim(string claimType, string claimValue)
{
    // get user claims
    var user = this.HttpContext.User as System.Security.Claims.ClaimsPrincipal;

    if (user != null)
    {
        // Get the specific claim if any
        return user.Claims.Any(c => c.Type == claimType && c.Value == claimValue);
    }

    return false;
}

public bool UserHasTradePricesReadClaim
{
    get
    {
        return UserHasSpecificClaim("TradePrices", "Read");
    }
}

Так где же роли?

У меня есть таблица, которая связывает роль с набором утверждений (по умолчанию). При настройке авторизации пользователя по умолчанию пользователь получает утверждения своей роли. У каждого пользователя может быть больше или меньше требований, чем указано по умолчанию. Чтобы упростить редактирование, список утверждений отображается контроллером и действиями (в строке), а затем перечислены другие утверждения. Кнопки используются с фрагментом Javascript для выбора набора действий, чтобы минимизировать «щелчки», необходимые для выбора утверждений. При сохранении заявки пользователей удаляются и добавляются все выбранные утверждения. Веб-приложение загружает заявки только один раз, поэтому любые изменения должны вызывать перезагрузку этих статических данных.

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

Pixelda
источник
4

Чтобы понять разницу между ролями и утверждениями, вы столкнетесь с ограничением ролей и почувствуете, как претензии возникают в связи с этими проблемами, поэтому я приведу вам 2 сценария, позволяющих осознать силу требований, когда роль не может решить эти проблемы:

1 - на вашем сайте должно быть два модуля (страницы, услуги и т. Д.), Первый модуль для детей (до 18 лет), другой для взрослых (старше 18 лет), ваша личность пользователя имеет дату рождения.

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

Роль - это логический тип данных, который вы можете иметь или не иметь. Роль роли не имеет солодовых значений.

2- ваш сайт имеет роль пользователя, и вы не хотите предотвращать доступ пользователей для обслуживания без изменения кода

в утверждениях вы можете создать политику UnderConstrain, которая, если истинный пользователь не может просматривать страницу, предоставит свойство авторизовать для роли пользователя.

Мохаммед Рашед
источник