Security中的@PostAuthorize、@PreFilter和@PostFilter详解

 更新时间:2023年11月07日 08:38:01   作者:JFS_Study  
这篇文章主要介绍了Security中的@PostAuthorize、@PreFilter和@PostFilter详解,@PostAuthorize是在方法调用完成后进行权限检查,它不能控制方法是否能被调用,只能在方法调用完成后检查权限决定是否要抛出AccessDeniedException,需要的朋友可以参考下

一、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可以用来控制一个方法是否能够被调用。 @PostAuthorize是在方法调用完成后进行权限检查,它不能控制方法是否能被调用,只能在方法调用完成后检查权限决定是否要抛出AccessDeniedException。

@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("wg.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。

三、使用 @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 的。

@PreFilter(filterTarget="ids", value="filterObject%2==0")
public void delete(List<Integer> ids, List<String> usernames) {
      ...
}

到此这篇关于Security中的@PostAuthorize、@PreFilter和@PostFilter详解的文章就介绍到这了,更多相关Security中@PreAuthorize内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • java Object类中常用API分享

    java Object类中常用API分享

    Object类是java中所有类的祖宗类,因此java中所有的类的对象都可以直接使用Object类中提供的一些方法,下面小编为大家整理了Object类中常用API,希望对大家有所帮助
    2023-10-10
  • 基于Jmeter生成测试报告过程图解

    基于Jmeter生成测试报告过程图解

    这篇文章主要介绍了基于Jmeter生成测试报告过程图解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-08-08
  • java中对字符串每个字符统计的方法

    java中对字符串每个字符统计的方法

    java中对字符串每个字符统计的方法,需要的朋友可以参考一下
    2013-03-03
  • Java函数式Lambda编程的使用学习(图文教程)

    Java函数式Lambda编程的使用学习(图文教程)

    文章介绍了Java中的Lambda表达式,它是一种替代匿名内部类的简洁方式,适用于函数式接口,通过Lambda表达式,可以简化代码,提高可读性,文章还讨论了方法引用的几种常见用法,包括静态方法引用、实例方法引用、特定类型方法引用和构造器引用
    2025-11-11
  • Spring Boot 编写Servlet、Filter、Listener、Interceptor的方法

    Spring Boot 编写Servlet、Filter、Listener、Interceptor的方法

    这篇文章给大家介绍了spring-boot中如何定义过滤器、监听器和拦截器,对Spring Boot 编写Servlet、Filter、Listener、Interceptor的相关知识感兴趣的朋友一起看看吧
    2017-07-07
  • Java8 如何移除两个相同的List对象

    Java8 如何移除两个相同的List对象

    这篇文章主要介绍了Java8 如何移除两个相同的List对象,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01
  • java实现微信小程序加密数据解密算法

    java实现微信小程序加密数据解密算法

    这篇文章主要为大家详细介绍了java实现微信小程序加密数据解密算法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-09-09
  • SpringBoot集成QQ第三方登陆的实现

    SpringBoot集成QQ第三方登陆的实现

    这篇文章主要介绍了SpringBoot集成QQ第三方登陆的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • 基于Java实现PDF文本旋转倾斜

    基于Java实现PDF文本旋转倾斜

    这篇文章主要介绍了基于Java实现PDF文本旋转倾斜,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-05-05
  • 在Java中实现线程安全的单例模式的常见方式

    在Java中实现线程安全的单例模式的常见方式

    单例模式是一种常用的软件设计模式,它确保一个类只有一个实例,并提供一个全局访问点,在多线程环境下,确保单例模式的线程安全性是非常重要的,因为多个线程可能会同时尝试创建实例,导致实例不唯一的问题,本文介绍了在Java中实现线程安全的单例模式有几种常见的方式
    2024-09-09

最新评论