Я ищу лучший способ обработки авторизации на уровне просмотра (где вы скрываете разметку на основе ролей пользователя).
Типичный способ сделать это с помощью тега Acegi Security authz следующим образом:
<authz:authorize ifAnyGranted="ROLE_FOO, ROLE_BAR, ROLE_BLAH">
<!-- protected content here -->
</authz:authorize>
Проблема такого подхода в том, что он быстро становится беспорядочным. Во-первых, вы либо жестко программируете роли пользователей, как указано выше, либо создаете файл констант, который дублирует их все. Во-вторых, при существующей схеме невозможно логически сгруппировать роли. Я полагаю, что одним из решений является определение отдельной роли для каждого элемента пользовательского интерфейса, , но тогда необходимо будет обновить уровень безопасности декларативного метода для бизнес-методов для каждого элемента пользовательского интерфейса (это будет хорошо?). Это также приведет к увеличению количества пользовательских ролей! Варианты использования для моего приложения на самом деле требуют очень мало, например, менеджер, менеджер супервизора, суперпользователь (может делать все), только чтение и т. Д.
Решение, которое приходит на ум, состоит в том, чтобы обрабатывать авторизируемые элементы пользовательского интерфейса подобно ресурсам сообщений. То есть определите серию «точек авторизации» в файле свойств, аналогичном файлу MessageResources. Мои первоначальные мысли таковы:
com.lingoswap.home.editUserNameButton.ifAnyGranted=ROLE_FOO, ROLE_BAR, ROLE_BLAH
com.lingoswap.home.deleteAccountButton.ifNotGranted=ROLE_NOOB
com.lingoswap.home.deleteAccountButton.ifAnyGranted=ROLE_ADMIN
...
Чтобы защитить контент на домашней странице, мы бы использовали другой защищенный тег (тот, который сильно заимствован у исходного authz, возможно, подкласса):
<security:protect component="com.lingoswap.home.editUserNameButton">
<!-- edit user name button -->
</security:protect>
<security:protect component="com.lingoswap.deleteAccountButton">
<!-- show the awesome delete account button that's not for nincompoops -->
</security:protect>
Преимущества этого подхода следующие:
- Простота тестирования - мы можем написать модульные тесты, которые проверяют сопоставления роли пользователя с элементом пользовательского интерфейса (конечно, он все еще должен использоваться в JSP)
- Ошибка проверки во время выполнения (и во время тестирования) - если в файле .properties неправильно указана роль пользователя, мы можем выдать исключение
- Легко настраивать пользовательские роли - команда требований постоянно уточняет пользовательские роли; было бы неплохо поменять их все в одном центральном месте
- Легко понять - мы можем сразу увидеть разрешения на роль пользователя для всего приложения
- Может быть выполнено DRYly (использование заполнителей Spring для группировки связанных ролей, например, $ {readOnlyGroup} может использоваться в файле свойств вместо фактических имен ролей
Недостатки вроде бы:
- Умеренная сложность
- Другие ??
Спасибо за ваш совет.
С уважением,
LES2