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

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

  • 查看器 - 查看学生详细信息
  • 编辑器 - 编辑学生详细信息
  • EXPORTER - 导出学生详细信息

  • 执行上述操作的 URI 如下所示:
  • GET - /content/{classId}/{studentId}/view
  • PUT - /content/{classId}/{studentId}
  • GET - /content/{classId}/{studentId}/export
  • POST - /content/{classId}/{studentId}/export

  • 请注意,URI 具有动态特性。此外,可以为给定的用户 User A 分配 VIEWERClass 1 角色和 EXPORTERClass 2 角色。

    在我的 spring-security 配置中,我只定义了两个权限 - ADMINISTRATORUSER
  • ADMINISTRATOR - 可以访问所有
  • USER - 可以访问除 /admin/* URI 之外的所有内容。

  • 角色 VIEWEREDITOREXPORTER 不是 spring-security 角色。现在我在限制用户访问他们无权访问的资源时遇到了问题。

    此外,如果用户没有正确的 EXPORTER,他甚至不应该看到导出按钮(放置在应用程序的某个位置)。也许我可以使用 spring 的 security 标签库来做到这一点。但这完全是另一个问题。

    我可以让他们知道 spring-security ,但问题是我应该把我读取 {studentId} ( @PathVariable ) 的逻辑放在哪里,并将其与当前登录的用户进行匹配,以检查他是否有权访问它。

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

    有没有更优雅的, Spring 安全的方式来做到这一点?

    欢迎任何想法。

    最佳答案

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

    这是您提供自己的 SecurityExpressionHandler 实现的方式。代码来自 spring security documentation :

    <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>
    

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

    关于java - Spring MVC中的自定义授权,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13766685/

    10-14 17:30
    查看更多