创建基于角色的 Web 应用程序的最佳方法是什么?
What is the best approach to create a role based web application?
我需要为学校创建一个 Web 应用程序,我需要有不同的角色,例如:
- 学生
- 教授
- 管理员
我需要在开始时登录,然后在输入凭据后应用程序需要重定向到主页。
这里的问题是:角色应该怎么处理?我应该为每个角色分配一个命名空间吗?即:students/index.jsp, professors/index.jsp, admin/index.jsp 或者所有角色都有一个共同的命名空间?像 home/index.jsp 这样的东西?然后使用 decorator/composite 模式让菜单根据角色有不同的选项?
对于这个问题,我知道我必须存储用户和角色,每个都有自己的 table,这个问题与处理 presentation/navigation/permission 角色和如何创建 webapp 更相关结构,即在 webapp 文件夹下有一个名为 students 的目录,另一个文件夹 admin 和另一个 students 以及关于我上面提到的要点(装饰器或复合模式)
当然,我不是在制作这么小的应用程序,而是想简化我面临的问题,以便创建一个基于 Web 的大角色应用程序,我相信这些是主要原则。
感谢您的宝贵时间和帮助。
您可以在数据库中使用一个字段来保存角色,但您可以阅读有关 ACL 和 RBAC 的内容。
我会推荐看一下 spring 安全性 https://projects.spring.io/spring-security/#quick-start
好问题。实际上这是完整的身份验证模块的扩展
对于您的小案例,公共页面是最佳解决方案。 根据角色,将出现所需的文本框或字段。
例如,如果 Role Student: subject,卷号将可用。但是如果教授登录到同一页面,他可以看到其他字段,如数字、出勤率等。
最简单的解决方案可以是: 创建主控 table,使用名称、ID、类型(是否有类型 student/Professor/Admin 等),并将此类型用作显示领域的决定性因素。
您的问题没有单一的答案。一切都取决于项目的结构。如果您提到的角色之间有很多共同点,那么最好对所有角色使用一个 index.jsp。这样您就不必复制通用逻辑(js
和 css
库、自定义通用脚本、视图和样式包含)。如果角色之间几乎没有共同点,那么最好为每个角色单独设置 index.jsp 文件,因为在程序执行期间将根据所选角色动态创建单个 index.jsp 文件(我认为仍然可以通过缓存来修复)。
在我们的项目中,我们使用单个 index.jsp 文件的方法。这首先是因为它们有很多共同的逻辑。但无论如何,决定权在你。
此外,如果您正在使用 Spring 安全性并且有可能在项目开发过程中添加新角色,那么 @PreAuthorize ("hasRole ('ROLE_USER')")
方法将不是很好。因为如果要向数据库添加新角色,则必须向项目添加大量代码才能授予此新角色所需的访问权限。因此,在这种情况下,最好通过权限授予访问权限。并在 roles
<-> permissions
之间创建关系 many to many
您绝对不希望为不同的角色设置单独的页面 ("namespaces"),因为这几乎不可避免地会导致代码重复。
您应该为每个功能创建一个页面,并根据用户的角色限制访问。 (例如,某些菜单项对学生不可见,但对教授和管理员显示。)
您绝对不应该尝试重新发明轮子来管理基于角色的权限,因为有用于此目的的经过实践检验的框架:正如其他人已经指出的那样,在 Java 世界中,Spring Spring Security 是正确的选择。
我认为 JSP 随着技术的发展,您可能应该开始学习 Angular。
由于获得工作 Spring / Angular 项目设置并非易事,我建议您使用 JHipster application generator,它通过向导指导您完成整个过程(您有仅回答一些问题——当被问及类型 select monolithic web application
时):然后它会根据现代建议创建一个具有基于角色的安全性的工作项目配置。
如果您想了解现代 Web 应用程序中基于角色的正确访问控制,我认为查看 JHipster 生成的应用程序中使用的解决方案是最好和最快的解决方案:
- 它使用 Spring 安全功能来限制 Java 中的呼叫
后端:在生成的项目
中寻找org.springframework.security.access.annotation.Secured
注解的用法
- 向 show/hide 某些 UI 展示了一些自定义前端技巧
基于角色的部分,像这样:
<h1 *jhiHasAnyAuthority="'ROLE_ADMIN'">Hello, admin user</h1>
,您可以轻松地将其应用到您自己的用例中。
- 您可以在 2 分钟内完成一个工作项目:非常适合学习(选择最简单的
monolithic web application
!)
拥有不同的页面违反了 DRY(不要重复自己)原则。
如果您想要一个简单的解决方案,请在您的网络应用程序中添加过滤器并在那里进行授权(委托给第 3 方应用程序)。您需要在组级别的 jsp 页面中添加条件,这样就不需要每次都更改。
您还可以使用 Spring 安全和 jdbc 身份验证。
我不确定我的解决方案能否解决您的问题。但就我而言,我是这样做的:
用户 0..n --- 0..m 角色
角色 0..n --- 0..m 权限
在您的情况下,您可能需要:
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.hasPrivilege
或 user.hasRole
保护您的视图。它会很好地工作。
P/s:抱歉我的英语不好。如果您需要任何东西,请在下面评论或评论到我的 gist
您可以创建不同的角色来访问不同的限制区域。例如,您可以拥有学生、教授和管理员角色。稍后您可以根据角色允许或阻止对内容的访问。 Spring Security 可能对你有好处。
我现在也有类似情况。我的项目需要身份验证和基于角色的授权。 Java 应用程序有许多可用的解决方案。我们的团队决定使用 Keycloak,这是一个额外的应用程序,您可以在其中处理大部分用户管理。它可以 运行 在单独的服务器上。不过,根据您的应用程序的范围,它可能有点矫枉过正。
据我所知,您尚未实施任何身份验证。这部分在我的案例中已经完成,主要是通过 Keycloak + Web 服务器中的配置完成的。
通常,您可以在大多数现代 Web 服务器中使用 Java EE 安全性进行授权。这将允许您使用 @RolesAllowed 之类的注释来授予或拒绝访问权限,并且可以在任何 Keycloak 的情况下工作。 Examples。这样您就可以为所有不同的角色保持统一的结构,并且只在请求执行之前才决定请求的合法性。
您可以创建 table 命名为 role_user 在此基础上您可以隔离
不同角色
尝试使用 spring 框架和 spring 安全开发您的网络应用
请参考下面的例子
http://websystique.com/spring-security/spring-security-4-role-based-login-example/
我相信你应该继续Spring Security
。它为您提供了许多开箱即用的功能,配置和维护您的应用程序变得更加容易。此外,您将能够更多地专注于构建应用程序的逻辑,而库会为您处理身份验证和授权(简单来说就是角色)。此外,它还有很多社区支持。
这是一个入门示例:Spring security - hello world
从上面的例子中,让我展示一段代码来更加强调我的主张:
@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 安全会检查用户名和密码是否正确。除此之外,它还会检查提供的用户名是否具有管理员角色。如果(密码和角色)都检查成功,那么只有您可以访问该页面。
因此,只需几行代码,您就可以通过应用程序的角色管理来控制整个安全性。
虽然在示例 post 中使用了硬编码的用户名,但插入数据库也很容易。但是这个例子是一个很好的入门方式,你可以自己看看它是否适合你的用例。
这个问题有多种解决方法。例如,您可以使用过滤器来验证和授权您的资源对不同 users/roles 的访问。除此之外,Spring 安全性提供内置机制来确保对网络资源的授权访问。除此之外,您可以在您的应用程序中创建一个管理面板,并且您可以将不同的页面分配给不同的角色(但是,这种方法涉及更多的编程工作)。您还可以考虑在 web.xml 中创建安全约束,并且可以将 web-resource-collections 与不同的角色相关联。
最佳方法是:Spring Security
但它需要时间和学习才能以正确的方式去做,所以在那之前我会做这样的事情:
- 假设您的数据库中有一个 table 用户。添加列名,例如user_rights.
- 在您的应用程序中,此列是您的 User 模型 class
的一个字段
- 创建一个检查此字段并根据需要处理角色的方法
例如,如果用户角色决定了他们可以访问哪些页面,这是一个简化的代码示例:
在您的网页开头:
<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 应用程序,我需要有不同的角色,例如:
- 学生
- 教授
- 管理员
我需要在开始时登录,然后在输入凭据后应用程序需要重定向到主页。
这里的问题是:角色应该怎么处理?我应该为每个角色分配一个命名空间吗?即:students/index.jsp, professors/index.jsp, admin/index.jsp 或者所有角色都有一个共同的命名空间?像 home/index.jsp 这样的东西?然后使用 decorator/composite 模式让菜单根据角色有不同的选项?
对于这个问题,我知道我必须存储用户和角色,每个都有自己的 table,这个问题与处理 presentation/navigation/permission 角色和如何创建 webapp 更相关结构,即在 webapp 文件夹下有一个名为 students 的目录,另一个文件夹 admin 和另一个 students 以及关于我上面提到的要点(装饰器或复合模式)
当然,我不是在制作这么小的应用程序,而是想简化我面临的问题,以便创建一个基于 Web 的大角色应用程序,我相信这些是主要原则。
感谢您的宝贵时间和帮助。
您可以在数据库中使用一个字段来保存角色,但您可以阅读有关 ACL 和 RBAC 的内容。
我会推荐看一下 spring 安全性 https://projects.spring.io/spring-security/#quick-start
好问题。实际上这是完整的身份验证模块的扩展 对于您的小案例,公共页面是最佳解决方案。 根据角色,将出现所需的文本框或字段。 例如,如果 Role Student: subject,卷号将可用。但是如果教授登录到同一页面,他可以看到其他字段,如数字、出勤率等。 最简单的解决方案可以是: 创建主控 table,使用名称、ID、类型(是否有类型 student/Professor/Admin 等),并将此类型用作显示领域的决定性因素。
您的问题没有单一的答案。一切都取决于项目的结构。如果您提到的角色之间有很多共同点,那么最好对所有角色使用一个 index.jsp。这样您就不必复制通用逻辑(js
和 css
库、自定义通用脚本、视图和样式包含)。如果角色之间几乎没有共同点,那么最好为每个角色单独设置 index.jsp 文件,因为在程序执行期间将根据所选角色动态创建单个 index.jsp 文件(我认为仍然可以通过缓存来修复)。
在我们的项目中,我们使用单个 index.jsp 文件的方法。这首先是因为它们有很多共同的逻辑。但无论如何,决定权在你。
此外,如果您正在使用 Spring 安全性并且有可能在项目开发过程中添加新角色,那么 @PreAuthorize ("hasRole ('ROLE_USER')")
方法将不是很好。因为如果要向数据库添加新角色,则必须向项目添加大量代码才能授予此新角色所需的访问权限。因此,在这种情况下,最好通过权限授予访问权限。并在 roles
<-> permissions
many to many
您绝对不希望为不同的角色设置单独的页面 ("namespaces"),因为这几乎不可避免地会导致代码重复。
您应该为每个功能创建一个页面,并根据用户的角色限制访问。 (例如,某些菜单项对学生不可见,但对教授和管理员显示。)
您绝对不应该尝试重新发明轮子来管理基于角色的权限,因为有用于此目的的经过实践检验的框架:正如其他人已经指出的那样,在 Java 世界中,Spring Spring Security 是正确的选择。
我认为 JSP 随着技术的发展,您可能应该开始学习 Angular。
由于获得工作 Spring / Angular 项目设置并非易事,我建议您使用 JHipster application generator,它通过向导指导您完成整个过程(您有仅回答一些问题——当被问及类型 select monolithic web application
时):然后它会根据现代建议创建一个具有基于角色的安全性的工作项目配置。
如果您想了解现代 Web 应用程序中基于角色的正确访问控制,我认为查看 JHipster 生成的应用程序中使用的解决方案是最好和最快的解决方案:
- 它使用 Spring 安全功能来限制 Java 中的呼叫 后端:在生成的项目 中寻找
- 向 show/hide 某些 UI 展示了一些自定义前端技巧
基于角色的部分,像这样:
<h1 *jhiHasAnyAuthority="'ROLE_ADMIN'">Hello, admin user</h1>
,您可以轻松地将其应用到您自己的用例中。 - 您可以在 2 分钟内完成一个工作项目:非常适合学习(选择最简单的
monolithic web application
!)
org.springframework.security.access.annotation.Secured
注解的用法
拥有不同的页面违反了 DRY(不要重复自己)原则。 如果您想要一个简单的解决方案,请在您的网络应用程序中添加过滤器并在那里进行授权(委托给第 3 方应用程序)。您需要在组级别的 jsp 页面中添加条件,这样就不需要每次都更改。
您还可以使用 Spring 安全和 jdbc 身份验证。
我不确定我的解决方案能否解决您的问题。但就我而言,我是这样做的:
用户 0..n --- 0..m 角色
角色 0..n --- 0..m 权限
在您的情况下,您可能需要:
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.hasPrivilege
或 user.hasRole
保护您的视图。它会很好地工作。
P/s:抱歉我的英语不好。如果您需要任何东西,请在下面评论或评论到我的 gist
您可以创建不同的角色来访问不同的限制区域。例如,您可以拥有学生、教授和管理员角色。稍后您可以根据角色允许或阻止对内容的访问。 Spring Security 可能对你有好处。
我现在也有类似情况。我的项目需要身份验证和基于角色的授权。 Java 应用程序有许多可用的解决方案。我们的团队决定使用 Keycloak,这是一个额外的应用程序,您可以在其中处理大部分用户管理。它可以 运行 在单独的服务器上。不过,根据您的应用程序的范围,它可能有点矫枉过正。
据我所知,您尚未实施任何身份验证。这部分在我的案例中已经完成,主要是通过 Keycloak + Web 服务器中的配置完成的。
通常,您可以在大多数现代 Web 服务器中使用 Java EE 安全性进行授权。这将允许您使用 @RolesAllowed 之类的注释来授予或拒绝访问权限,并且可以在任何 Keycloak 的情况下工作。 Examples。这样您就可以为所有不同的角色保持统一的结构,并且只在请求执行之前才决定请求的合法性。
您可以创建 table 命名为 role_user 在此基础上您可以隔离
不同角色
尝试使用 spring 框架和 spring 安全开发您的网络应用 请参考下面的例子 http://websystique.com/spring-security/spring-security-4-role-based-login-example/
我相信你应该继续Spring Security
。它为您提供了许多开箱即用的功能,配置和维护您的应用程序变得更加容易。此外,您将能够更多地专注于构建应用程序的逻辑,而库会为您处理身份验证和授权(简单来说就是角色)。此外,它还有很多社区支持。
这是一个入门示例:Spring security - hello world
从上面的例子中,让我展示一段代码来更加强调我的主张:
@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 安全会检查用户名和密码是否正确。除此之外,它还会检查提供的用户名是否具有管理员角色。如果(密码和角色)都检查成功,那么只有您可以访问该页面。
因此,只需几行代码,您就可以通过应用程序的角色管理来控制整个安全性。
虽然在示例 post 中使用了硬编码的用户名,但插入数据库也很容易。但是这个例子是一个很好的入门方式,你可以自己看看它是否适合你的用例。
这个问题有多种解决方法。例如,您可以使用过滤器来验证和授权您的资源对不同 users/roles 的访问。除此之外,Spring 安全性提供内置机制来确保对网络资源的授权访问。除此之外,您可以在您的应用程序中创建一个管理面板,并且您可以将不同的页面分配给不同的角色(但是,这种方法涉及更多的编程工作)。您还可以考虑在 web.xml 中创建安全约束,并且可以将 web-resource-collections 与不同的角色相关联。
最佳方法是:Spring Security
但它需要时间和学习才能以正确的方式去做,所以在那之前我会做这样的事情:
- 假设您的数据库中有一个 table 用户。添加列名,例如user_rights.
- 在您的应用程序中,此列是您的 User 模型 class 的一个字段
- 创建一个检查此字段并根据需要处理角色的方法
例如,如果用户角色决定了他们可以访问哪些页面,这是一个简化的代码示例:
在您的网页开头:
<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 应用程序。