Я ищу лучший способ обработки авторизации на уровне представления (когда вы скрываете разметку на основе ролей пользователя).
Типичный способ сделать это — использовать тег authz Acegi Security следующим образом:
<authz:authorize ifAnyGranted="ROLE_FOO, ROLE_BAR, ROLE_BLAH">
<!-- protected content here -->
</authz:authorize>
Проблема с таким подходом в том, что он быстро становится беспорядочным. Во-первых, вы либо жестко кодируете роли пользователей, как указано выше, либо создаете файл констант, который дублирует их все. Во-вторых, с текущей схемой невозможно логически сгруппировать роли. Я полагаю, что одно из решений состоит в том, чтобы определить отдельную роль для каждого элемента пользовательского интерфейса, , но тогда безопасность на уровне декларативного метода для бизнес-методов необходимо будет обновить для каждого элемента пользовательского интерфейса (хорошо ли это?). strike> Это также приведет к увеличению количества ролей пользователей! Вариантов использования для моего приложения на самом деле требуется очень мало, например, менеджер, супервизор менеджера, суперпользователь (может делать все), только чтение и т. д.
Решение, которое приходит на ум, состоит в том, чтобы относиться к авторизуемым элементам пользовательского интерфейса аналогично ресурсам сообщений. То есть определите серию «точек авторизации» в файле свойств, аналогичном файлу 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, мы можем создать исключение.
- Легко настроить роли пользователей — команда по требованиям постоянно уточняет роли пользователей; было бы неплохо поменять их все в одном центральном месте
- Легко понять - мы можем с первого взгляда просмотреть разрешения роли пользователя для всего приложения.
- Можно сделать СУХИМ (используя заполнители свойства Spring для группировки связанных ролей, например, ${readOnlyGroup} можно использовать в файле свойств вместо фактических имен ролей
Недостатки кажутся:
- Умеренная сложность
- Другие??
Спасибо за совет.
С уважением, ЛЕС2.