Spring MVC中的自定义授权


问题内容

我们有一个应用程序,管理员可以在其中创建用户,并将角色分配给特定类型的实体。

例如,如果调用实体Student,则应用程序的用户具有不同级别的特权,例如:

  • 查看者-查看学生详细信息
  • 编辑-编辑学生详细信息
  • 出口商-出口学生详细信息

执行上述操作的URI如下所示:

  • GET -- /content/{classId}/{studentId}/view
  • PUT -- /content/{classId}/{studentId}
  • GET -- /content/{classId}/{studentId}/export
  • POST -- /content/{classId}/{studentId}/export

请注意,URI具有动态性质。此外,给定用户User A可以分配VIEWER的角色Class 1EXPORTERClass 2

在我的spring-security配置中,我仅定义了两个权限- ADMINISTRATORUSER

  • ADMINISTRATOR -可以访问所有内容
  • USER-可以访问/admin/*URI 以外的所有内容。

该角色VIEWEREDITOREXPORTER不弹簧安全角色。现在,在限制用户访问他们没有权限的资源时遇到了一个问题。

另外,如果用户没有EXPORTER权限,他甚至都不会看到“ 导出”
按钮(位于应用程序的某个位置)。也许我可以使用spring的securitytaglib 做到这一点。但这完全是另一个问题。

我可以使他们了解弹簧安全性,但问题是我应该把读取{studentId}@PathVariable)的逻辑放在哪里,并将其与当前登录的用户进行匹配,以检查他是否可以访问它。

我什至想到了创建一个HandlerInterceptor监听器的想法/content/*。但是我将不得不做一些丑陋的事情,例如解析URI,自己提取第二个路径参数,然后对照数据库进行检查。

有没有更优雅,更安全的弹簧方式?

任何想法欢迎。


问题答案:

您可以提供自己的Spring安全性SecurityExpressionHandler。只需扩展DefaultWebSecurityExpressionHandler并覆盖即可createSecurityExpressionRoot。默认情况下,此方法返回的实例WebSecurityExpressionRoot。您的实现可以扩展此类并添加其他方法,这些方法将在spring安全配置中使用。

这是您提供自己的SecurityExpressionHandler实现的方式。该代码来自spring安全文档

<security:global-method-security pre-post-annotations="enabled">
    <security:expression-handler ref="expressionHandler"/>
</security:global-method-security>

<bean id="expressionHandler" class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
    <property name="permissionEvaluator" ref="myPermissionEvaluator"/>
</bean>

答案是否提供足够的信息,或者您需要进一步的帮助?