【问题标题】:PreAuthorize issue on common spring NoRepositoryBean base interface常见 spring NoRepositoryBean 基本接口上的 PreAuthorize 问题
【发布时间】:2016-01-21 22:02:39
【问题描述】:

我正在尝试编写一个通用的 SecurePagingAndSorting 存储库,它将检查 CRUD 操作的安全性,以节省在所有 JPA 存储库中重复相同的 PreAuthorize(具有不同的权限)。

下面是一个简单的例子:

@NoRepositoryBean
public interface SecuredPagingAndSortingRepository<T, ID extends Serializable>     extends PagingAndSortingRepository<T, ID> {

@Override
@PreAuthorize("hasPermission(#id, domainType, 'delete')) 
 void delete(ID id);

}

现在问题在于 domainType 参数,因为这是一个通用接口,它不能被硬编码。从派生自 SecurePagingRepository 的存储库中获取域类型的最佳方法是什么。

【问题讨论】:

    标签: java spring spring-security spring-data spring-data-jpa


    【解决方案1】:

    我看到的最佳解决方案是编写自己的接口PermissionEvaluator 实现,然后将其注入到安全上下文中替换默认的。

    如果您尝试这种方式,扩展类 AclPermissionEvaluator 将为您节省大量已经由 Spring 管理的代码,并确保向后兼容。

    【讨论】:

    • 我正在查看 Spring Security ACL,但我仍然看不到上面的 hasPermission 通用查询如何填充在 AclPermissionEvauluator 需要执行此操作时读取的 domainType。看来我仍然需要在上面的场景中使用 hasPermission(#id, 'org.company.MyDomainObject',delete) 污染每个存储库实现
    • 我可以看到正在进行通用查询增强的工作,但似乎还没有完成。
    • @CCob 例如,您可以为域类型使用自定义值(在超类中),然后在这种情况下在 hasPermission 方法中执行自定义逻辑。否则请致电super.hasPermission(...) 以确保向后兼容。
    【解决方案2】:

    我最终确定了这个解决方案。 PreAuthorize 可以使用 @ 字符在 Spel 表达式中使用任何 bean。

    @Override
    @PreAuthorize("hasPermission(#id, @security.getDeletePermission(#id,#this.this))) 
    void delete(ID id);    
    }
    

    因此,当调用 'security' bean 的 getDeletePermission 函数时,#this.this 参数将转换为相关的 SimpleJpaRepository。这使我们能够确定有问题的具体存储库并返回所需的权限名称

    【讨论】:

      猜你喜欢
      • 2012-07-19
      • 2011-03-06
      • 2013-07-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-21
      • 1970-01-01
      相关资源
      最近更新 更多