Render JSF component based on user role
If your web.xml
is declared as Servlet 3.0 (which implicitly relates to 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">
then you can take benefit of being able to invoke methods with arguments in EL like as ExternalContext#isUserInRole()
:
rendered="#{facesContext.externalContext.isUserInRole('ADMIN')}"
Note that this requires a Servlet 3.0 capable container, but since you're using Glassfish 3 (which supports Servlet 3.0), it should work without any issues.
Also note that if you're using Facelets instead of JSP, then you've the HttpServletRequest
available as #{request}
in EL, allowing you the following shorter expression:
rendered="#{request.isUserInRole('ADMIN')}"
- Conditionally displaying JSF components
- Conditional rendering of non-JSF components (plain vanilla HTML and template text)
- JSF: How control access and rights in JSF?
In response to @wasimbhalli, there are two reasons I have found that the expression would always return false:
The role name is case sensitive.
rendered="#{facesContext.externalContext.isUserInRole('ADMIN')}"
may returnfalse
, but tryrendered="#{facesContext.externalContext.isUserInRole('admin')}"
, or rendered="#{facesContext.externalContext.isUserInRole('Admin')}".You have to define your roles in both
web.xml
(or as annotations) and map it inglassfish-web.xml
.
The following is how to specify a role in 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>
The following is how to map the authentication group to the role in 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>
In my testing it was necessary to do the mapping even when the names were the same, as I show in my example code. Also in my testing, I tried to only define the mapping and only to define the role in web.xml
, and neither worked. I needed both, as specifying the role name in the correct case.