首页 文章

基于用户角色渲染JSF组件

提问于
浏览
15

如何根据登录用户的角色呈现JSF组件?我知道外部上下文暴露了主体,但是我应该如何在JSF中正确地进行呈现?在JSP中它会是这样的

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

我如何以最好的方式在JSF中编写这个?我最好的猜测是渲染属性绑定到一个返回布尔值的支持bean的方法,但如果我必须只为管理员渲染一些导航项,那将引入一个无关的支持bean ...

Glassfish V3.1,JSF 2.x

3 回答

  • 34

    如果您的 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),因此它应该没有任何问题 .

    另请注意,如果HttpServletRequest在EL中_259501_可用作 #{request} ,则允许使用以下较短的表达式:

    rendered="#{request.isUserInRole('ADMIN')}"
    
  • 5

    在回答@wasimbhalli时,有两个原因我发现表达式总是返回false:

    • 角色名称区分大小写 . rendered="#{facesContext.externalContext.isUserInRole('ADMIN')}" 可能会返回 false ,但请尝试 rendered="#{facesContext.externalContext.isUserInRole('admin')}" 或渲染= "#{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 中定义角色,但两者都没有效果 . 我需要两个,因为在正确的情况下指定角色名称 .

  • 0

    将角色存储在会话属性中,并使用渲染属性进行比较 .

    例如 rendered="#{yoursessionbean.userRole == Roles.ADMIN}"

相关问题