Запретить по умолчанию - определенно хороший подход, но иногда имеет смысл иметь больше гибкости и определять, как правила (или политики) могут быть объединены.
Вот что говорится в стандарте:
Полная политика, применимая к конкретному запросу решения, может состоять из ряда отдельных правил или политик. Например, в приложении для обеспечения конфиденциальности личных данных владелец личной информации может определять определенные аспекты политики раскрытия информации, тогда как предприятие, которое является хранителем информации, может определять некоторые другие аспекты. Чтобы принять решение об авторизации, должна быть возможность объединить две отдельные политики для формирования единой политики, применимой к запросу. Источник
- Имейте в виду, что XACML не просто возвращает разрешение или отказ. Он может возвращать
Permit
, Deny
, NotApplicable
и Indeterminate
. - Политики XACML - это не простой список проверок, который вы обычно видите в правилах управления доступом к сети / брандмауэра. Политики XACML - это дерево (или несколько деревьев) политик, где чем глубже, тем лучше, а чем уже, тем лучше. Как только вы начнете строить деревья, вам понадобится механизм разрешения конфликтов, известный как алгоритм комбинирования.
Распространенным шаблоном при написании политик XACML является определение иерархической структуры политик. Вы делаете это, потому что хотите, чтобы ваша политика была управляемой. Итак, давайте представим, что вы - Acme In c. и у вас есть 5 бизнес-единиц, и у вас есть 5 API, которые, в свою очередь, имеют 5 методов.
Ваша политика может выглядеть как следующая заглушка (в alfa ):
policyset acme{
apply firstApplicable
policyset bu1{
target clause unit == "bu1"
apply firstApplicable
policyset financeApi{
target clause apiPath == "/finance"
apply firstApplicable
policy buyTrade{
target clause objectType == "trade"
apply firstApplicable
rule denyIfAmountTooLarge{
deny
condition trade.amount > user.allowedAmount
on deny{
obligation notify {
message = "You cannot approve this transaction because..."
}
}
}
}
}
}
}
Если бы он был отклонен по умолчанию и сначала отклонил, то я не смог бы иметь несколько политик параллельно (для BU1, BU2 ...). Я не смог бы так легко вкладывать политики. Также может быть вероятность, что я по ошибке откажу или разрешаю доступ. Мне нужно контролировать на каждом уровне, каким может быть результат и что делать, если мы получим NotApplicable
или Indeterminate
обратно.
Эффективная структура политики ... для времени выполнения и времени разработки
Одним из основных недостатков списков управления доступом или правил стиля NA C является тот факт, что вы потенциально можете получить слишком много правил, и трудно понять, какие правила описывают какой доступ. В NA C, например, как узнать, разрешен или запрещен UDP на данном порте. Из какого диапазона IP-адресов?
Более продвинутые языки политик, такие как XACML и ALFA, дают вам возможность создавать дерево политик. Это означает, что вы можете организовать свои политики в виде древовидной структуры, которая:
- может быть оценена быстрее - просто отсеките ветви, которые не применяются
- можно управлять и понимать (людьми) легче. Прокрутка списка из более чем 1000 правил неуправляема. Однако открытие ветвей и сворачивание других упрощает поиск нужной части.
- можно использовать повторно. Представьте, что правило для порта 8080 UDP и порта 8080 TCP одинаковое. Больше не нужно их дважды переписывать. Вы можете просто связать один полис / правило с другим и накапливать выгоды.
У разных полисов разные цели
Представьте, что вы страховая компания, обрабатывающая претензии. Ваша базовая политика такова: агент по заявкам может просматривать заявки только в своем регионе и может утверждать выплаты только в пределах их лимита. Итак, у вас есть разрешение, если u.region = c .region и u.approvalLimit> = c .amount.
Но что, если это чрезвычайная ситуация, вы хотите, чтобы все ваши сотрудники обслуживали все регионы. Итак, теперь вам нужна политика, которая может переопределить ограничение региона. Вы не можете сделать это в плоском списке, структура отрицает выигрыш. Здесь XACML / ALFA пригодится, потому что синтаксис и структура достаточно богаты для решения этих сценариев. ios.
Вот еще несколько, которые имеют смысл
Найдите все причины для отрицания доступ
Иногда вы не хотите отрицать, как только можете. Вы хотите сообщить конечному пользователю все причины отказа в доступе. Например, обработчик претензий не может одобрить претензию, потому что (а) сумма слишком велика, (б) регион не совпадает с регионом сотрудника и (c) существует конфликт интересов. Если вы сообщили пользователю частичную информацию, вы бы заставили пользователя повторить попытку утверждения 3 раза и получить отказ 3 раза.
Найдите первую причину для отказа в доступе
Это противоположно предыдущее утверждение и наиболее распространенный паттерн: вы хотите раскрывать как можно меньше и отрицать как можно скорее. Ваша модель может работать здесь.
Разрешить, только если все проверки разрешены
Это также известно как шаблон Берга. Вместо того, чтобы говорить:
- отклонить, если регион указан неверно
- отклонить, если сумма слишком велика
- разрешить утверждение претензии
Вы могли бы сказать allow if - region is right - amount is under limit
В этом случае вы хотите собрать все решения о разрешениях, а затем перевернуть их, если это необходимо. Это требует переопределения разрешений и запрета-если-разрешение. Вы не сможете сделать это, используя только стратегию запрета.
Внимание
Будьте осторожны с политиками запрета. Что, если вы напишете политику, которая гласит:
- запретить въезд из Канады в США, если гражданство не США.
В XACML, если по какой-то причине значение для гражданства нет, то в доступе не будет отказано. Мы не знаем, является ли пользователь американцем или нет. Так что вам нужно подумать и о наличии ценности.
Дополнительная литература
Axiomatics имеет отличную запись об алгоритмах объединения . Предлагаю вам это проверить.