创建基于角色的 Web 应用程序的最佳方法是啥?

Posted

技术标签:

【中文标题】创建基于角色的 Web 应用程序的最佳方法是啥?【英文标题】:What is the best approach to create a role based web application?创建基于角色的 Web 应用程序的最佳方法是什么? 【发布时间】:2018-07-06 04:22:23 【问题描述】:

我需要为学校创建一个 Web 应用程序,并且我需要具有不同的角色,例如:

学生 教授 管理员

我需要在开始时登录,然后在输入凭据后,应用程序需要重定向到主页。

这里的问题是:我应该如何处理这些角色?我应该为每个角色都有一个命名空间吗?即:students/index.jsp、professor/index.jsp、admin/index.jsp 或所有角色都有一个共同的命名空间?像 home/index.jsp 这样的东西?然后使用装饰器/复合模式让菜单根据角色有不同的选项?

对于这个问题,我知道我必须将用户和角色存储在自己的表中,这个问题与处理演示/导航/权限角色以及如何创建 webapp 结构(即有一个目录)更相关在 webapp 文件夹下名为 students、另一个文件夹 admin 和另一个学生以及关于我上面提到的一点(装饰器或复合模式)

当然,我不会做这么小的应用程序,但我想简化我面临的问题,以便创建一个基于 Web 的大型应用程序,我相信这些是主要原则。

感谢您的宝贵时间和帮助。

【问题讨论】:

使用弹簧安全 这不是对您问题的直接回答,只是提示您考虑基于声明而不是基于角色的身份验证。更多信息在这里linkedin.com/pulse/…。 【参考方案1】:

您可以使用数据库中的字段来保存角色,但您可以阅读有关 ACL 和 RBAC 的信息。

【讨论】:

【参考方案2】:

我会推荐看看 spring security https://projects.spring.io/spring-security/#quick-start

【讨论】:

【参考方案3】:

好问题。实际上这个扩展是完整的认证模块 对于您的小案例通用页面是最好的解决方案。根据角色所需的文本框或字段将出现。 例如,如果角色学生:学科,卷号将可用。但是如果教授登录到同一页面,他可以看到其他字段,例如数字、出勤率等。 最简单的解决办法是: 创建一个主表,有Name、Id、TYPE(有学生/教授/管理员等类型),并以此TYPE作为显示字段的决定性因素。

【讨论】:

【参考方案4】:

您的问题没有单一的答案。一切都取决于项目的结构。如果您提到的角色之间有很多共同点,那么最好对所有角色使用单个 index.jsp。然后您不必复制通用逻辑(jscss 库、自定义通用脚本、视图和样式包含)。如果角色之间几乎没有共同点,那么最好为每个角色有单独的 index.jsp 文件,因为单个 index.jsp 文件将在程序执行期间根据所选角色动态创建(我认为仍然可以通过缓存来修复)。

在我们的项目中,我们使用单个 index.jsp 文件的方法。这首先是因为它们有很多共同的逻辑。但在任何情况下都将由您做出决定。

另外,如果您使用的是Spring Security,并且在项目开发过程中可能会添加新的角色,那么@PreAuthorize ("hasRole ('ROLE_USER')") 的方法将不是很好。因为如果您将新角色添加到数据库中,您将不得不向项目中添加大量代码以授予该新角色所需的访问权限。因此,在这种情况下,最好通过权限授予访问权限。并在roles permissions

之间创建关系many to many

【讨论】:

【参考方案5】:

您绝对不希望为不同的角色设置单独的页面(“命名空间”),因为这几乎不可避免地会导致代码重复。

您应该为每个功能设置一个页面,并根据用户的角色限制访问。 (例如,某些菜单项对学生不可见,但对教授和管理员显示。)

您绝对不应该尝试重新发明***来管理基于角色的权限,因为有经过实战验证的框架可用于此目的:正如其他人已经指出的那样,在 Java 世界中,Spring 和 Spring Security 是要走的路。

我认为 JSP 作为技术正在老化,所以你应该开始学习Angular。

由于获得一个有效的 Spring / Angular 项目设置并非易事,我建议您使用JHipster application generator,它会通过向导引导您完成整个过程(当被问及类型时,您只需回答一些问题选择monolithic web application):然后它会根据现代建议创建一个具有基于角色的安全性的工作项目配置。

如果您想了解现代 Web 应用程序中正确的基于角色的访问控制,那么查看 JHipster 生成的应用程序中使用的解决方案是我认为最好和最快的解决方案:

它使用 Spring Security 特性来限制 Java 中的调用 后端:在生成的项目中查找org.springframework.security.access.annotation.Secured注解的用法 展示了一些自定义前端技巧来显示/隐藏某些 UI 基于角色的部分,如下所示: <h1 *jhiHasAnyAuthority="'ROLE_ADMIN'">Hello, admin user</h1>,您可以轻松地将其用于您自己的用例。 您可以在 2 分钟内完成一个工作项目:非常适合学习(选择最简单的 monolithic web application!)

【讨论】:

【参考方案6】:

拥有不同的页面违反了 DRY(不要重复自己)原则。 如果您想要一个简单的解决方案,请在您的 Web 应用程序中添加过滤器并在那里进行授权(委托给第 3 方应用程序)。您需要在组级别的 jsp 页面中添加条件,这样就不需要每次都更改。

您还可以使用 Spring 安全性和 jdbc 身份验证。

【讨论】:

【参考方案7】:

我不确定我的解决方案能否解决您的问题。但就我而言,我这样做如下:

用户 0..n --- 0..m 角色

角色 0..n --- 0..m 权限

Production code

在您的情况下,您可能需要:

Admin 无法查看、编辑学生成绩。 Student 可以查看分数但不能编辑。 Professor 可以查看、编辑、添加分数。

你可以这样做:

角色

ROLE_SCORE_EDITOR ROLE_SCORE_VIEWER

特权

OP_READ_SCORE OP_CREATE_SCORE OP_UPDATE_SCORE OP_DELETE_SCORE ---> 可能不需要这个,但作为一个例子就足够了。

角色 - 特权

ROLE_SCORE_EDITOR

OP_READ_SCORE OP_CREATE_SCORE OP_UPDATE_SCORE

ROLE_SCORE_VIEWER

OP_READ_SCORE

用户 - 角色

管理员(这真的取决于你,在我的情况下我应该留空)

教授

ROLE_SCORE_EDITOR

学生

ROLE_SCORE_VIEWER

然后在您的模板中使用user.hasPrivilegeuser.hasRole 保护您的视图。它会正常工作的。

P/s:对不起,我的英语不好。如果您需要任何东西,请在下面评论或评论到我的gist

【讨论】:

【参考方案8】:

您可以创建不同的角色来授予对不同受限区域的访问权限。例如,您可以拥有学生、教授和管理员角色。稍后您可以根据角色允许或阻止对内容的访问。 Spring Security 可能对你有好处。

【讨论】:

【参考方案9】:

我现在也有类似的情况。我的项目需要身份验证和基于角色的授权。有许多可用于 Java 应用程序的解决方案。我们的团队决定使用Keycloak,这是一个额外的应用程序,您可以在其中处理大部分用户管理。它可以在单独的服务器上运行。不过,根据您的应用程序的范围,这可能有点矫枉过正。

在我看来,您还没有实现任何身份验证。这部分在我的案例中已经完成,主要是通过 Keycloak + Web 服务器中的配置完成的。

通常,您可以在大多数现代 Web 服务器中使用 Java EE 安全性进行授权。这将允许您使用 @RolesAllowed 之类的注释来授予或拒绝访问权限,并且无论 Keycloak 如何都可以工作。 Examples。通过这种方式,您可以为所有不同角色保持统一的结构,并且仅在请求执行之前确定请求的合法性。

【讨论】:

【参考方案10】:

您可以创建基于命名的表,如role_user,基于您可以隔离

不同的角色

【讨论】:

【参考方案11】:

尝试使用 Spring 框架和 Spring Security 开发您的 Web 应用程序 请参考以下示例 http://websystique.com/spring-security/spring-security-4-role-based-login-example/

【讨论】:

【参考方案12】:

我相信你应该继续使用Spring Security。它为您提供了许多开箱即用的功能,并且配置和维护您的应用程序变得非常容易。此外,当库为您处理身份验证和授权(简单来说就是角色)时,您将能够更专注于构建应用程序的逻辑。此外,它还有很多社区支持。

这是一个开始的例子:Spring security - hello world

从上面的例子中,让我展示一个 sn-p 的代码来更加重视我的主张:

@Override
    protected void configure(HttpSecurity http) throws Exception 

      http.authorizeRequests()
        .antMatchers("/admin/**").access("hasRole('ROLE_ADMIN')")
        .antMatchers("/dba/**").access("hasRole('ROLE_ADMIN') or hasRole('ROLE_DBA')")
        .and().formLogin();

    

所以上面的配置会做的是,每当你尝试访问 /admin 页面或管理页面下的任何 url 时,例如/admin/profile/admin/home 等,您将被要求进行身份验证(在您的情况下使用用户名和密码)。 spring security会检查用户名和密码是否正确。除此之外,它还将检查提供的用户名是否具有角色 admin。如果(密码和角色)检查都成功,那么只有您可以访问该页面。

因此,只需几行代码,您就可以通过应用程序的角色管理来控制整个安全性。

虽然在示例帖子中,使用了硬编码的用户名,但插入数据库也很容易。但该示例是入门的好方法,您可以自己查看它是否适合您的用例。

【讨论】:

【参考方案13】:

有多种方法可以解决这个问题。例如,您可以使用过滤器来验证和授权不同用户/角色访问您的资源。除此之外,Spring Security 提供了内置机制来确保对 Web 资源的授权访问。除此之外,您可以在应用程序中创建管理面板,并且可以将不同的页面分配给不同的角色(但是,这种方法涉及更多的编程工作)。您还可以考虑在 web.xml 中创建安全约束,并且可以将 web-resource-collections 与不同的角色相关联。

【讨论】:

【参考方案14】:

最好的方法是:Spring Security

但它需要时间和学习才能以正确的方式做到这一点,所以在那之前我会做这样的事情:

    假设您的数据库中有一个表user。添加列名,例如user_rights。 在您的应用程序中,此列是您的 User 模型类的一个字段 创建一个检查此字段并根据需要处理角色的方法

例如,如果用户角色决定了他们可以访问哪些页面,这是一个简化的代码示例:

在您网页的开头:

<h:body>

<f:metadata>
    <f:viewAction action="#userService.checkIfLogged()" />
    <f:viewAction action="#userService.accessCheck('page 2')" />
</f:metadata>

在你的 bean 方法中:

@Override
@Transactional
public String accessCheck(String page) 
    try 
       HttpSession sess = Util.getSession();
       String user = sess.getAttribute("username").toString();
       Session session = this.sessionFactory.getCurrentSession();
       User logged = (User) session.createQuery("select u from User u where 
                     u.username = :logged").setParameter("logged", 
                                            user).uniqueResult();
       if (page.equals("page 1")) 
        if (logged.getRights().equals("simple")) 
            return "profile?faces-redirect=true";
         
        else 
            return "#";
        
       ... etc.

希望这有帮助,我仍然推荐 Spring 框架的功能,但同时这对我来说非常适合小型 Web 应用程序。

【讨论】:

以上是关于创建基于角色的 Web 应用程序的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

创建一个 TOKEN 系统来验证 Web 服务调用的最佳方法是啥?

对于 asp.net mvc Web 应用程序,将文本文件存储到 Sql Server 数据库中的最佳方法是啥?

基于地理区域或地址创建 Rails 验证的最佳方法是啥?

创建基于时间的动态事件(如建筑施工时间等)的最佳方法是啥? [关闭]

使用尽可能少的资源,模拟挂起的 Web 应用程序的最佳方法是啥?

基于需要外部 API 调用的现有列创建新的 Spark 数据框列的最佳方法是啥?