2011-01-20 51 views
15

¿Cómo puedo representar los componentes JSF en función de la función de un usuario conectado? Sé que el contexto externo expone los principios, pero ¿cómo debo hacer el renderizado correctamente en JSF? En JSP sería algo así comoRenderizar el componente JSF en función del rol de usuario

<% isUserInRole(Roles.ADMIN) { %> 
<button>Edit!</button> 
<% } %> 

¿Cómo escribo esto en JSF de la mejor manera posible? Mi mejor estimación es el atributo renderizado vinculado al método de un bean de respaldo que devuelve un booleano, pero que introduciría un bean de respaldo irrelevante si tuviera que renderizar algunos elementos de navegación solo para administradores ...

Glassfish V3.1, JSF 2.x

+1

JSF 1.xo 2.x? – BalusC

+0

2.x, Glassfish 3.1 – TC1

+0

En el futuro, agregue la etiqueta '[jsf-2.0]' para indicar que :) – BalusC

Respuesta

31

Si su web.xml está declarada como Servlet 3.0 (que se refiere implícitamente a 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"> 

entonces usted puede tomar ventaja de ser capaz de llamar a los métodos con argumentos en EL similares como ExternalContext#isUserInRole():

rendered="#{facesContext.externalContext.isUserInRole('ADMIN')}" 

Tenga en cuenta que esto requiere un contenedor compatible con Servlet 3.0, pero ya que está utilizando Glassfish 3 (que admite Servlet 3.0), debería funcionar sin problemas.

También tenga en cuenta que si usted está utilizando Facelets en vez de JSP, entonces usted tiene la HttpServletRequest disponible como #{request} en EL, lo que le permite la siguiente expresión más corta:

rendered="#{request.isUserInRole('ADMIN')}" 
+0

Es de hecho Servlet 3.0, pero de alguna manera entre todo este alboroto de la sesión de examen había olvidado que habían agregado llamadas de método a JSF ... Muchas gracias :) – TC1

+1

No es específicamente JSF, es EL (esos '# {}' cosas) que cuenta. Si ejecuta JSF 2.0, por ejemplo, Servlet 2.5 (que implica JSP/EL 2.1), no funcionará. Se presenta en JSP/EL 2.2. – BalusC

+0

He definido roles para cada usuario que usa JDBC Realm. Pero la expresión anterior siempre devuelve "falso" para cualquier usuario. ¿Debo agregar algo más para que funcione? – wasimbhalli

0

Almacene el rol en el atributo de sesión y simplemente compare el uso del atributo representado.

p. Ej. rendered="#{yoursessionbean.userRole == Roles.ADMIN}"

+0

Esa fue una de mis ideas al principio, pero el usuario puede tener una infinidad de roles basados ​​en su grupos. Solo funcionaría realmente si el usuario solo tuviese un rol ... – TC1

+0

@ TC1 - acuerde, luego tendrá que recurrir a una llamada de método o esperar si surge alguna otra solución. – niksvp

5

En respuesta a @wasimbhalli, hay dos razones que he encontrado que la expresión siempre volvería falsa:

  1. El nombre de la función es sensible a mayúsculas. rendered="#{facesContext.externalContext.isUserInRole('ADMIN')}" puede devolver false, pero pruebe rendered="#{facesContext.externalContext.isUserInRole('admin')}", o rendered = "# {facesContext.externalContext.isUserInRole ('Admin')}".

  2. tiene que definir sus papeles en tanto web.xml (o como anotaciones) y el mapa en glassfish-web.xml.

La siguiente es la forma de especificar un papel en 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> 

La siguiente es la forma de asignar el grupo de autenticación al papel en 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> 

En mis pruebas fue necesario para hacer el mapeo incluso cuando los nombres eran los mismos, como muestro en mi código de ejemplo. También en mis pruebas, traté de definir solo el mapeo y solo definir el rol en web.xml, y tampoco funcionó. Necesitaba ambos, como especificar el nombre del rol en el caso correcto.

Cuestiones relacionadas