【问题标题】:Spring object level permissions without spring security ACL没有 Spring Security ACL 的 Spring 对象级权限
【发布时间】:2013-09-30 15:19:26
【问题描述】:

我想在我的项目中实现对象级权限。更具体地说,会有一个用户、一个学校和一个学生类。每个学生将属于一所学校。系统的每个用户也将属于一所学校。因此,系统的每个用户只能访问属于其学校的学生。

我在很多地方读到过,这可以在 Spring Security ACL 的帮助下完成。这需要在我的数据库中创建许多 ACL_ 表(如果我没记错的话是 4 个)并且对我的每个对象都具有特定的权限!所以我的 ACL_ENTRY 中的行数与对象数一样多!

这对我的应用程序来说太过分了,因为对象已经知道谁可以访问它,谁不能访问它 - 为什么我还要额外的 acl_entry?我想要的是检查要更新的对象是否属于特定用户并返回是否允许。选择也是如此——只返回属于特定用户的对象。

据我所知,这必须在我的数据访问层中完成——如果我在其他任何地方这样做,我就会遇到查询问题(因为我需要一一检查所有对象以查看它们是否属于特定用户)。对于我的数据访问,我使用spring-data,其接口扩展了 JpaRepository。我可以添加自己的保存/选择方法吗?如何从这些方法中获取 User 对象?有没有人为了帮助我开始做类似的事情?

【问题讨论】:

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


    【解决方案1】:

    试一试。您可以通过在应用程序中实现 Spring AOP 来实现对象级别的安全性。根据您的要求,我将在此处提供一个示例。

    //在用户模型访问前执行

    @Before("within(org.school.model.*)")
     public void doCheckSchoolUsers() throws <any custom exception or Exception class>
     {
    //Write your code here to get the current user and validate the user based on   your business requirements. 
    if(the user is not authorized)
            throw new Exception<or your custome exception> //You can catch this        exception any of your filter and redirect accordingly. 
    

    您可以通过以下两种方式验证您的学生对象。

    1. 如果您的方法返回 Student 对象或与一些对象集合一起返回,您可以捕获该方法返回的所有对象。

      @AfterReturning(pointcut = "execution(* 
      com.mkyong.customer.bo.CustomerBo.addCustomerReturnValue(..))",returning= "result")
       public void logAfterReturning(JoinPoint joinPoint, Object result) 
       {
      System.out.println("logAfterReturning() is running!");
      System.out.println("hijacked : " + joinPoint.getSignature().getName());
      System.out.println("Method returned value is : " + result);
      System.out.println("******");
      

      }

    2. 在 aop 方法中获取参数。

      public String log(ProceedingJoinPoint jp) throws Throwable 
      {
            System.out.println("Spring AOP: Around advice");
             Object[] args=jp.getArgs();
            if(args.length>0){
              System.out.print("Arguments passed: ");
              for (int i = 0; i < args.length; i++) {
                System.out.print("Arg"+(i+1)+":"+args[i]);
                args[i]=":Spring AOP removed the argument";
              }
           }
           Object result=jp.proceed(args);
           return result.toString()+" :Result is also modified";
      }
      

    更多详情:http://docs.spring.io/spring/docs/2.5.5/reference/aop.html

    【讨论】:

    • 看起来不错,但是如何在选择时过滤我的结果?另外,如何在 AOP 方法 inside 中找到 Student 对象?我对 AOP 不是很熟悉 :(
    • 数据访问过滤呢?
    • 我没有收到您关于“数据访问过滤”的问题
    • 如何过滤数据层的结果?当我想为用户检索学生时,我只想返回属于用户学校的学生。但是出于性能原因,这需要在数据库级别完成,否则 所有 学生将从数据库中返回(然后将在更高级别选择正确的学生)。
    猜你喜欢
    • 2013-11-07
    • 2013-04-17
    • 2014-05-11
    • 2019-07-18
    • 1970-01-01
    • 2013-10-14
    • 2011-09-02
    • 2011-11-20
    相关资源
    最近更新 更多