当前位置: 首页 > 知识库问答 >
问题:

基于角色控制表单输入的属性文件

韦星文
2023-03-14

我正在构建的应用程序的需求要求用户角色是动态的,它们将存储在数据库中,并且还将映射到应用程序的功能(表单),也存储在数据库中。

限制角色访问特定页面并不困难,但要求还规定表单输入必须根据角色进行定制,这意味着输入可以是强制性的或非强制性的、可见的或不可见的、只读的或不基于角色的。

我控制这些限制的方法是为每个角色创建一个属性文件,该文件将应用程序中所有表单的所有输入存储为键,并将一个长字符串存储为值,我们在其中定义输入的状态,如下所示:

用户输入。性质

# form.input=mandatory:visibility

searchBooks.bookName=true:true
searchBooks.bookCategory=false:true
searchBooks.authorName=false:false

管理输入。性质

searchBooks.bookName=true:true
searchBooks.bookCategory=false:true
searchBooks.authorName=false:true

然后执行一些神奇的Java代码,每当访问表单时,从特定用户角色的文件中读取其输入属性,并解析这些值,以便为rendered=“”required=“”属性提供正确的值

这可能是一个解决方案,但应用程序的输入远不止是一本书的名称和类别,这意味着我将放置大量必需的和呈现的属性,这将使JSF页面在托管bean中有大量变量时看起来很难看。

我的问题有更好的方法/框架/解决方案吗?


共有1个答案

艾善
2023-03-14

我认为您的方法是正确的,我将继续使用您的方法,包括创建多个属性文件,每个用户一个,但我们不会使用任何“托管bean中的大量变量”。

因此,第一步包括使用单个资源包前缀()管理多个资源属性

我们首先在faces config文件中定义ResourceBundle:

<application>
      <resource-bundle>
         <base-name>UserMessages</base-name>
         <var>msgs</var>
      </resource-bundle>
</application>

UserMessages是一个ResourceBundle,我们将在其中实现允许我们在属性文件之间切换的逻辑(假设yourpackage.user-inputs是用户输入.properties的完全限定名):

import java.util.Enumeration;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

import javax.faces.context.FacesContext;

public class UserMessages extends ResourceBundle {

    public UserMessages() {
        // we are loading user-inputs.properties as the default properties file
        setParent(getBundle("yourpackage.user-inputs", FacesContext.getCurrentInstance()
                .getViewRoot().getLocale()));
    }

    @Override
    protected Object handleGetObject(String key) {
        // we could just return parent.getObject(key) but we want to respect JSF recommandations
        try {
            return parent.getObject(key);
        } catch (MissingResourceException e) {
            return "???" + key + "???";
        }
    }

    @Override
    public Enumeration<String> getKeys() {

        return parent.getKeys();
    }

    // this is the method that will allow us to switch between our .properties
    public void setResourceBundle(String basename) {
        setParent(getBundle(basename, FacesContext.getCurrentInstance()
                .getViewRoot().getLocale()));
    }
} 

为了从一个属性文件切换到另一个,我们将需要使用方法setResourceBundle(String basename),我们刚刚在上面的类中声明,所以在托管bean中,您将在其中声明您的业务逻辑,并打算根据用户的角色切换文件,需要注入bundle,如:

//don't forget adding getters and setters or you end with NullPointerException
@ManagedProperty("#{msgs}")
private UserMessages userMesssages;

然后,要切换到另一个文件(admin inputs.properties),只需如下使用它:

//yourpackage.admin-inputs is the fully qualified name
userMesssages.setResourceBundle("yourpackage.admin-inputs");

注意:您可以通过这种方式(如上所述)只在请求范围的Bean中注入捆绑包,要在更广泛的范围中使用它,请参阅:从Bean中的属性文件读取i18n变量

现在,由于我们可以轻松地从用户输入切换到管理输入,最后一步是最简单的。

坏消息是,当使用这种方法时,您需要将rendered=“”required=“”属性添加到您愿意管理的每个输入(但不要忘记,好消息是您不需要管理托管bean中的变量;)。

首先,您需要在xhtml文件的顶部添加JSTL名称空间声明:

xmlns:fn="http://java.sun.com/jsp/jstl/functions"

您可以在javadocs中找到更多关于JSTL函数的信息,关于函数substringAfter

返回特定子字符串后面的字符串子集。

例子:

  P.O. Box: ${fn:substringAfter(zip, "-")}

函数substring前

返回特定子字符串之前的字符串的子集。

例子:

  Zip (without P.O. Box): ${fn:substringBefore(zip, "-")}

其次,由于字符串的第一部分表示所需的属性:

//Returns the substring of msgs['searchBooks.authorName'] before the first occurrence of the separator ':'    
required="${fn:substringBefore(msgs['searchBooks.authorName'], ':')}"

第二部分:

//Returns the substring of msgs['searchBooks.authorName'] after the first occurrence of the separator ':'.
rendered="${fn:substringAfter(msgs['searchBooks.authorName'], ':')}"
  • JSF国际化f: loadbundle或通过face-config:性能点
  • JSF 2.0中的应用程序#getResourceBundle()和ResourceBundle#getBundle()之间的区别
  • 如何去除周围???当在bundle中找不到消息时
  • JavaServer中的上下文敏感资源包条目面临应用程序-超越纯语言,区域

 类似资料:
  • 问题内容: 是否可以使用任何基于角色的开源访问控制系统? 问题答案: 布兰登·萨维奇(Brandon Savage)在他的PHP软件包“ ApplicationACL ” 上做了一个演示,该演示可能会或可能不会完成基于角色的访问。PHPGACL可能也能正常工作,但是我不能肯定地告诉您。 但是,我可以告诉您的是Zend Framework 的Zend_ACL组件将执行基于角色的设置(但是您必须子类化

  • 角色定义 [role_definition] 是RBAC角色继承关系的定义。 Casbin 支持 RBAC 系统的多个实例, 例如, 用户可以具有角色及其继承关系, 资源也可以具有角色及其继承关系。 这两个 RBAC 系统不会互相干扰。 此部分是可选的。 如果在模型中不使用 RBAC 角色, 则省略此部分。 [role_definition] g = _, _ g2 = _, _ 上述角色定义表

  • 以下内容是 xingzhou 对 kubernetes 官方文档的翻译,原文地址 https://k8smeetup.github.io/docs/admin/authorization/rbac/ 基于角色的访问控制(Role-Based Access Control, 即”RBAC”)使用”rbac.authorization.k8s.io” API Group实现授权决策,允许管理员通过Ku

  • 一个更友好的域内基于角色的访问控制的API。 这个API是Management API的子集。 RBAC用户可以使用这个API来简化代码。 参考 全局变量 e 是 Enforcer 实例。GoNode.jsPHP.NETRust e, err := NewEnforcer("examples/rbac_model.conf", "examples/rbac_policy.csv") const

  • 读后http://en.wikipedia.org/wiki/Role-based_access_control看到人们建立授权/访问控制的方式,我想到了这个问题:“为什么我们在检查用户是否被允许执行X操作时检查用户的角色,而不是检查他们的权限?” 这就是我所理解的,用户有角色,角色有权限,这就是用户可以拥有权限的方式(用户不能明确地拥有分配给它的权限,它通过拥有角色获得权限) 我认为,在处理添加

  • 我正在开发一个mean stack web应用程序,它包含基于登录用户角色的差异访问。有几个不同的角色,如管理员,政府,志愿者等。 1.如何基于角色管理前端? 目前,我正在为每个角色设置全局标志,如isAdmin、is志愿者、isGovt等,并根据其值,使用 这是正确的说法吗。如果不是,请建议处理UI的正确方法。 2.如果用户没有授权,如何管理后端和重定向路由? 目前我正在尝试使用angular权