Как правильно использовать isUserInRole(роль)

Чтобы предотвратить роль пользователя от выполнения действия.

  1. Пример 1. Роль "администратор" - единственная роль, которой разрешено выполнять действие уничтожения.
  2. Пример 2. Любая роль, отличная от "гостевой", может выполнять действие CREATE.

В реальном случае у меня есть это:

public String delete() {
 if(FacesContext.getCurrentInstance().getExternalContext().isUserInRole("administrator"){
   //.....the action to perform
 }
 return "Denied";
}

Я хотел бы использовать аннотацию @RolesAllowed() EJB пока я не использую EJB, но ManagedBeans. Итак, вопрос: есть ли способ использовать много ролей одновременно? Некоторое решение! Пример: если в действии должно быть разрешено 3 роли (администратор, модератор, менеджер). Я обязан сделать:

if (FacesContext.getCurrentInstance().getExternalContext().isUserInRole("administrator")
    || FacesContext.getCurrentInstance().getExternalContext().isUserInRole("manager") 
    || .....) {
  //....
}

И это является болью, чтобы воспроизвести на всех методах. Что-то вроде сотен методов:(

3 ответа

Решение

Это нужно контролировать со стороны вида. Разве вы не находите это очень раздражающим, когда вы видите на каком-то сайте кнопку, на которую у вас недостаточно прав, чтобы нажать и таким образом получить пугающую страницу с ошибкой, когда вы это делаете?

Просто визуализируйте кнопку на стороне просмотра только тогда, когда у пользователя есть требуемая роль, иначе скрывайте ее полностью.

<h:commandButton value="Delete" action="#{bean.delete}" 
    rendered="#{request.isUserInRole('administrator')}" />

Это не чувствительно к взлому (CSRF), поскольку JSF еще раз проверяет условие на этапе применения значений запроса.

Что касается использования нескольких условий и повторения одного и того же снова и снова в одном представлении, рассмотрите возможность использования <c:set> дать ему короткий псевдоним. Вы даже можете поместить его в верхнюю часть какого-либо главного шаблона, чтобы он был доступен для всех дочерних шаблонов.

<c:set var="isPowerUser" value="#{request.isUserInRole('manager') or request.isUserInRole('administrator')}" scope="request" />
...
<h:commandButton rendered="#{isPowerUser}" />
...
<h:commandButton rendered="#{isPowerUser}" />

Вы можете сократить это, переместив логику в служебный метод:

public class AuthorizationUtils {
    public static boolean isUserInRoles(String[] roles) {
        for (String role : roles) {
            if (FacesContext........isUserInRole(role)) {
                return true;
            }
        }

        return false;
    }
}

И затем вызвать его с помощью:

if (AuthorizationUtils.isUserInRoles(new String[] {"administrator", "moderator"})) {
    ..
}

Если вы используете CDI, вы можете сделать перехватчик, который обрабатывает @RolesAllowed аннотирование

@Mediterran81: В общем, вы ищете решение для авторизации на основе bean-метода... как вы создаете экземпляры своих управляемых bean-компонентов? Вы можете ввести простой формат XML:

<bean class="">
 <method name="">
  <role> xyz</role>
 </method>
</bean>

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

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