zoukankan      html  css  js  c++  java
  • spring security中@PreAuthorize、@PostAuthorize、@PreFilter和@PostFilter四者的区别

    spring security中可以通过表达式控制方法权限:

      Spring Security中定义了四个支持使用表达式的注解,分别是@PreAuthorize、@PostAuthorize、@PreFilter和@PostFilter。其中前两者可以用来在方法调用前或者调用后进行权限检查,后两者可以用来对集合类型的参数或者返回值进行过滤。要使它们的定义能够对我们的方法的调用产生影响我们需要设置global-method-security元素的pre-post-annotations=”enabled”,默认为disabled。

       <security:global-method-security pre-post-annotations="disabled"/>

     使用@PreAuthorize和@PostAuthorize进行访问控制

           @PreAuthorize可以用来控制一个方法是否能够被调用。

    @Service

    public class UserServiceImpl implements UserService {

       @PreAuthorize("hasRole('ROLE_ADMIN')")

       public void addUser(User user) {

          System.out.println("addUser................" + user);

       }

       @PreAuthorize("hasRole('ROLE_USER') or hasRole('ROLE_ADMIN')")

       public User find(int id) {

          System.out.println("find user by id............." + id);

          return null;

       }

    }

      在上面的代码中我们定义了只有拥有角色ROLE_ADMIN的用户才能访问adduser()方法,而访问find()方法需要有ROLE_USER角色或ROLE_ADMIN角色。使用表达式时我们还可以在表达式中使用方法参数。

    public class UserServiceImpl implements UserService {

       /**

        * 限制只能查询Id小于10的用户

       */

       @PreAuthorize("#id<10")

       public User find(int id) {

          System.out.println("find user by id........." + id);

          return null;

       }

       /**

        * 限制只能查询自己的信息

        */

       @PreAuthorize("principal.username.equals(#username)")

       public User find(String username) {

          System.out.println("find user by username......" + username);

          return null;

       }

       /**

        * 限制只能新增用户名称为abc的用户

        */

       @PreAuthorize("#user.name.equals('abc')")

       public void add(User user) {

          System.out.println("addUser............" + user);

       }

    }

       在上面代码中我们定义了调用find(int id)方法时,只允许参数id小于10的调用;调用find(String username)时只允许username为当前用户的用户名;定义了调用add()方法时只有当参数user的name为abc时才可以调用。

       有时候可能你会想在方法调用完之后进行权限检查,这种情况比较少,但是如果你有的话,Spring Security也为我们提供了支持,通过@PostAuthorize可以达到这一效果。使用@PostAuthorize时我们可以使用内置的表达式returnObject表示方法的返回值。

    下面这一段示例代码:

    @PostAuthorize("returnObject.id%2==0")

       public User find(int id) {

          User user = new User();

          user.setId(id);

          return user;

       }

           上面这一段代码表示将在方法find()调用完成后进行权限检查,如果返回值的id是偶数则表示校验通过,否则表示校验失败,将抛出AccessDeniedException。需要注意的是@PostAuthorize是在方法调用完成后进行权限检查,它不能控制方法是否能被调用,只能在方法调用完成后检查权限决定是否要抛出AccessDeniedException。

    使用@PreFilter和@PostFilter进行过滤

           使用@PreFilter和@PostFilter可以对集合类型的参数或返回值进行过滤。使用@PreFilter和@PostFilter时,Spring Security将移除使对应表达式的结果为false的元素。

       @PostFilter("filterObject.id%2==0")

      public List<User> findAll() {

          List<User> userList = new ArrayList<User>();

          User user;

          for (int i=0; i<10; i++) {

             user = new User();

             user.setId(i);

             userList.add(user);

          }

          return userList;

       }

           上述代码表示将对返回结果中id不为偶数的user进行移除。filterObject是使用@PreFilter和@PostFilter时的一个内置表达式,表示集合中的当前对象。当@PreFilter标注的方法拥有多个集合类型的参数时,需要通过@PreFilter的filterTarget属性指定当前@PreFilter是针对哪个参数进行过滤的。

    如下面代码就通过filterTarget指定了当前@PreFilter是用来过滤参数ids的。

    1.  
      @PreFilter(filterTarget="ids", value="filterObject%2==0")
    2.  
       
    3.  
      public void delete(List<Integer> ids, List<String> usernames) {
    4.  
       
    5.  
      ...
    6.  
       
    7.  
  • 相关阅读:
    【第40套模拟题】【noip2011_mayan】解题报告【map】【数论】【dfs】
    【模拟题(63550802...)】解题报告【贪心】【拓扑排序】【找规律】【树相关】
    【模拟题(电子科大MaxKU)】解题报告【树形问题】【矩阵乘法】【快速幂】【数论】
    IMemoryBufferReference and IMemoryBufferByteAccess
    SoftwareBitmap and BitmapEncoder in Windows.Graphics.Imaging Namespace
    Windows UPnP APIs
    编译Android技术总结
    Windows函数转发器
    Two Ways in Delphi to Get IP Address on Android
    Delphi Call getifaddrs and freeifaddrs on Android
  • 原文地址:https://www.cnblogs.com/gzhbk/p/13402572.html
Copyright © 2011-2022 走看看