Компонент Render JSF на основе роли пользователя
Как мне отображать компоненты JSF на основе зарегистрированной роли пользователя? Я знаю, что внешний контекст раскрывает принципы, но как я должен правильно выполнять рендеринг в JSF? В JSP это будет что-то вроде
<% isUserInRole(Roles.ADMIN) { %>
<button>Edit!</button>
<% } %>
Как я могу написать это в JSF наилучшим образом? Мое лучшее предположение - это атрибут rendered, привязанный к вспомогательному bean методу, который возвращает логическое значение, но это приведет к нерелевантной поддержке bean, если мне придется отображать некоторые элементы навигации только для администраторов...
Glassfish V3.1, JSF 2.x
Ответы
Ответ 1
Если ваш web.xml
объявлен как Servlet 3.0 (который неявно относится к JSP/EL 2.2)
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
тогда вы можете воспользоваться возможностью вызова методов с аргументами в EL, например ExternalContext#isUserInRole()
:
rendered="#{facesContext.externalContext.isUserInRole('ADMIN')}"
Обратите внимание, что для этого требуется контейнер с поддержкой Servlet 3.0, но поскольку вы используете Glassfish 3 (который поддерживает Servlet 3.0), он должен работать без каких-либо проблем.
Также обратите внимание, что если вы используете Facelets вместо JSP, у вас есть HttpServletRequest
, доступный как #{request}
в EL, позволяя вам следующее более короткое выражение:
rendered="#{request.isUserInRole('ADMIN')}"
Ответ 2
В ответ на @wasimbhalli есть две причины, по которым я нашел, что выражение всегда возвращает false:
-
Имя роли чувствительно к регистру.
rendered="#{facesContext.externalContext.isUserInRole('ADMIN')}"
может возвращать false
, но попробуйте
rendered="#{facesContext.externalContext.isUserInRole('ADMIN')}"
или rendered = "# {facesContext.externalContext.isUserInRole('Admin')}".
-
Вы должны определить свои роли как в web.xml
(или как аннотации), так и поместить их в glassfish-web.xml
.
Ниже приведено описание того, как указать роль в web.ml
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
<security-role>
<role-name>admin</role-name>
</security-role>
</web-app>
Ниже показано, как сопоставить группу проверки подлинности с ролью в glassfish-web.xml
.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE glassfish-web-app PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Servlet 3.0//EN" "http://glassfish.org/dtds/glassfish-web-app_3_0-1.dtd">
<glassfish-web-app>
<security-role-mapping>
<role-name>admin</role-name> <!-- name defined in web.xml or annotations -->
<group-name>admin</group-name><!-- name from authentication mechanism -->
</security-role-mapping>
</glassfish-web-app>
В моем тестировании необходимо было выполнить сопоставление, даже если имена были одинаковыми, как показано в моем примере кода. Также в моем тестировании я попытался определить только отображение и только определить роль в web.xml
и не работал. Мне нужны были оба, указав имя роли в правильном случае.
Ответ 3
Сохранить роль в атрибуте сеанса и просто сравнить это с помощью атрибута rendered.
например. rendered="#{yoursessionbean.userRole == Roles.ADMIN}"