Реализация пользовательской функции XACML в Balana
После большой работы, пытаясь установить пользовательскую функцию внутри balana (для использования в условиях применения в политиках), я пытаюсь спросить здесь. В основном, какая документация говорит вам об установке новой функции внутри движка Balana: 1) вставьте в конфиг что-то вроде этого:
<functionFactory name="func" useStandardFunctions="true">
<general>
<function class="singlerequestandpolicybalanatester.GpsFunction"/>
</general>
<!-- <target>
<function class="singlerequestandpolicybalanatester.GpsFunction"/>
</target>
<condition>
<function class="singlerequestandpolicybalanatester.GpsFunction"/>
</condition>
-->
</functionFactory>
и конечно реализовать этот класс
public class GpsFunction extends FunctionBase {
public static final String NAME_GPS = "coolfunctiongps";
public static Set getSupportedIdentifiers() {
Set set = new HashSet();
set.add(NAME_GPS);
return set;
}
public GpsFunction() {
super(NAME_GPS, 0, StringAttribute.identifier, false, 3, 3, BooleanAttribute.identifier, false);
System.out.println(NAME_GPS);
}
@Override
public EvaluationResult evaluate(List inputs, EvaluationCtx context) {
blablabla
Действительно, переопределение getupportedidentifiers это даже не требуется, но что угодно..
Теперь, когда Balana запускается, вы видите, что ваш класс инициализирован, конструктор называется. Тогда даже после того, как balana инициализируется, вы можете сделать:
Set sup = balana.getFunctionGeneralFactory().getSupportedFunctions();
Iterator<String> it = sup.iterator();
System.out.println("General:");
while (it.hasNext()) {
String thisfunc = (String) it.next();
System.out.println(thisfunc);
}
и вы видите, что ваша функция загружена и готова к работе. Ницца. Нет, провал. После отладки с использованием моей собственной сборки ядра Balana с большим количеством отладочных сообщений вы ясно видите, когда элемент Apply разрешает время выполнения в одной политике и Apply.getInstance(он вызывается и фабрике передается вместе с именем вашей функции в фабрику THAT). нет вашей функции, так что все, что вы получаете, это исключительная среда выполнения с "Unknown FunctionId". Я даже пытался вручную установить фабрику функций, например:
FunctionFactoryProxy ff = StandardFunctionFactory.getNewFactoryProxy();
// ff.getGeneralFactory().addFunction(new GpsFunction());
balana.setFunctionGeneralFactory(ff.getGeneralFactory());
balana.setFunctionConditionFactory(ff.getConditionFactory());
balana.setFunctionTargetFactory(ff.getTargetFactory());
balana.getFunctionGeneralFactory().addFunction(new GpsFunction());
PDP pdp = new PDP(balana.getPdpConfig());
Опять же, я могу видеть свою функцию в этом прокси, но в конце дня, во время выполнения, когда двигатель разрешает
<Rule Effect="Deny" RuleId="itsatrap">
<Target/>
<Condition>
<Apply FunctionId="coolfunctiongps">
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
<AttributeDesignator AttributeId="attributoid" Category="attributocategory" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true" />
</Apply>
</Apply>
</Condition>
</Rule>
это исключение, Unknow FunctionId. Ясно что-то упускаю, и я спрашиваю, кто может выполнить РАБОЧИЙ пример пользовательской функции внутри и применить элемент. Спасибо всем.
1 ответ
После долгого серфинга в источнике балана, я могу ответить сам. Может быть, кто-то найдет это полезным. Забудьте все о balana.xml. Вам нужно сделать это вручную, и это удивительно просто. (Но не нашёл этого:))
Он состоит из 4 шагов.
1) Получить новый заводской прокси-сервер из standardFunctionFactory. Итак, теперь у вас есть прокси с изменяемыми стандартами (я имею в виду стандартные функции).
2) Получить общие фабрики от этого прокси (Общие, если вы хотите, чтобы видимость вашей функции была где-либо, или просто Targetfactory, если вы хотите только target или conditionfactory, если только в разделе условий политик).
3) Добавьте вашу новую функцию на эту фабрику
4) TRICKY PART Навязывайте абстрактную FunctionFactory для использования вашего нового прокси во время выполнения. Это делается путем указания статического члена defaultproxy на новый.
Итак, короткая история:
FunctionFactoryProxy ff = StandardFunctionFactory.getNewFactoryProxy();
FunctionFactory f = ff.getGeneralFactory();
f.addFunction(new GpsFunction());
FunctionFactory.setDefaultFactory(ff);
Готово.
В случае, если кто-то упустит, как создать свою собственную новую функцию, вам нужно просто расширить FunctionBase, переопределить оценку, вызвать суперкоструктор внутри вашего собственного конструктора и переопределить открытый статический Set getSupportedIdentifiers().
До свидания.