Объединение логических выражений при определении приоритетов выражений

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

  • operationName определяет, к какой операции применяется правило.

  • SubjectSpecification определяет, должно ли правило применяться к конкретному Subject или нет. Например, следующее будет соответствовать любому предмету в подразделении А.

    subjectSpec = new MyAppSubjectSpecification(division: 
    Division.SOME_DIVISION)
    
  • AccessSpecification определяет фактическое выражение правила.

  • AccessType определяет, разрешает ли соответствие правило или запрещает доступ.

  • RulePriorityStrategy это определяет, как правила должны быть унаследованы.

На вопрос, скажем, что наше приложение Subject имеет следующую структуру {divisionId, sectionId, groupId, userId } и что RulePriority утверждает, что чем конкретнее SubjectSpecification тем выше его приоритет.

Например, правило, ориентированное на конкретный userId будет иметь приоритет над правилом, ориентированным на division к которому принадлежит этот пользователь.

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

Например, со следующими правилами:

- Grant OperationA to all where (A && B) || C
- Grant OperationA to division A where D
- Deny Operation to user xyz where B && E

Здесь я ожидаю, что пользователь xyz (который принадлежит к разделу A) будет разрешен, когда C || D || (A && B && !E),

То, как я планировал использовать финал по наследству grant а также allow Правила таковы:

canPerformOperation = grantSpec.isSatisfiedBy(...) and not (denySpec.isSatisfiedBy(...))

В этом случае кажется, что комбинирование следующим образом будет работать, но это не во всех сценариях (например, когда allow должен переопределять отказ).

GR = Grant rule
DN = Deny rule

allowed = (GRn || GRn+1 ... || GRn+x)) && !(DRn || DRn+1 ... || DRn+x)
allowed = ((A && B) || C) || D) && !(B && E)

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

0 ответов

Другие вопросы по тегам