Spirng Security使用注解对方法做权限安全控制

 Spring Security默认情况下是关闭了对方法级的安全控制。可以通过xml或者是在添加了@Configuration注解的bean上添加@EnableGlobalMethodSecurity来开启对方法级别的安全控制。Spring Security 支持三种方法级注解, 分别是 JSR-205/Secured 注解/prePostEnabled,可以在开启对方法级的安全控制时设置。

方法级的安全控制开启

通过xml开启对方法级的安全控制:

<global-method-security secured-annotations="enabled" />
<global-method-security jsr250-annotations="enabled" />
<global-method-security pre-post-annotations="enabled" />

通过注解的方式开启对方法级的安全控制:

//@Secured 注解
@EnableGlobalMethodSecurity(securedEnabled=true)
//JSR-205 注解
@EnableGlobalMethodSecurity(jsr250Enabled=true)
//@PreAuthorize 类型的注解(支持 Spring 表达式)
@EnableGlobalMethodSecurity(prePostEnabled=true)

prePostEnabled支持 Spring EL 表达式,而其他两种注解方式不支持。使用Spring EL表达式可以更灵活地定制一些权限规则。

@Secured注解的使用

只有满足角色的用户才能访问被注解的方法, 否则将会抛出 AccessDenied 异常.

@Secured("ROLE_TELLER","ROLE_ADMIN"), 该方法只允许 ROLE_TELLER 或 ROLE_ADMIN 角色的用户访问.
@Secured("IS_AUTHENTICATED_ANONYMOUSLY"), 该方法允许匿名用户访问.

JSR-205注解的使用

@DenyAll注解, 拒绝所有的访问
@PermitAll 注解, 运行所有访问
@RolesAllowed({"USER","ADMIN"}), 该方法只允许有 ROLE_USER 或 ROLE_ADMIN 角色的用户访问.

PreAuthorize的使用

@PreAuthorize 注解, 在方法调用之前, 基于表达式结果来限制方法的使用.
@PostAuthorize 注解, 允许方法调用, 但是如果表达式结果为 false, 将抛出一个安全性异常.
@PostFilter 注解, 允许方法调用, 但必要按照表达式来过滤方法的结果.
@PreFilter 注解, 允许方法调用, 但必须在进入方法之前过来输入值.

1、使用returnObject对返回值多检查

对于 @PostAuthorize 和 @PostFilter 注解, 可以在表达式中使用 returnObject 保留名, returnObject 代表着被注解方法的返回值, 我们可以使用 returnObject 保留名对注解方法的结果进行验证.

比如:

@PostAuthorize ("returnObject.owner == authentication.name")
public Book getBook();

2、使用#号引用方法参数

在表达式中, 可以使用 #arg 的形式来代表注解方法中的参数 arg.

比如:

@PreAuthorize ("#book.owner == authentication.name")
public void deleteBook(Book book);

使用@P注解或@Param注解给参数设置别名

@PreAuthorize("#c.name == authentication.name")
public void doSomething(@P("c") Contact contact);

3、内置的表达式列表

  • hasRole([role]) :如果有当前角色, 则返回 true(会自动加上 ROLE_ 前缀)
  • hasAnyRole([role1, role2]): 如果有任一角色即可通过校验, 返回true,(会自动加上 ROLE_ 前缀)
  • hasAuthority([authority]) :如果有指定权限, 则返回 true
  • hasAnyAuthority([authority1, authority2]): 如果有任一指定权限, 则返回true
  • principal:获取当前用户的 principal 主体对象
  • authentication:获取当前用户的 authentication 对象,
  • permitAll:总是返回 true, 表示全部允许
  • denyAll:总是返回 false, 代表全部拒绝
  • isAnonymous():如果是匿名访问, 返回true
  • isRememberMe(): 如果是remember-me 自动认证, 则返回 true
  • isAuthenticated(): 如果不是匿名访问, 则返回true
  • isFullAuthenticated(): 如果不是匿名访问或remember-me认证登陆, 则返回true
  • hasPermission(Object target, Object permission)
  • hasPermission(Object target, String targetType, Object permission) 


版权声明:著作权归作者所有。

相关推荐

Python安全创建目录的方法

在介绍Python安全创建目录之前,先举一个不安全创建目录的方式:if not os.path.exists(directory):     os.makedirs(directory) 在例子里,先判断目录是否存在,然后创建目录。这种方式是不安全的,它会导致竞争条件。在os.path.exists()和os.makedirs()之间的时

Java 8使用parallel Stream测试StringBuilder线程安全

我们知道StringBuilder不是线程安全的,但如何证明它非线程安全呢?测试StringBuilder是否线程安全一个简单的思路如下:模拟多个线程并发向StringBuilder实例添加字符,最后检测builder.toString().length()的值是否为添加字符的次数,如果非线程安全会出现builder.toString().length()的值与添加字符的次数不一致。Java&nb

Kotlin使用kotlin-kapt插件支持Android的注解处理

在Kotlin可以使用kapt插件来支持Android的注解处理。在Gradle配置kotlin-kapt插件如下:在app的build.gradle添加插件apply plugin: 'kotlin-kapt' 使用kapt添加注解依赖java使用annotationProcessor 添加的依赖改为使用kapt。例如添加dagger依赖dependencies {

Linux:使用visudo设置用户sudo权限

visudo我们可以修改/etc/sudoers文件来设置用户的sudo权限,修改/etc/sudoers一定要使用visudo命令,它可以让我们比较安全的修改此文件。visudo有以下特性:锁定文件避免多个同时编辑检查语法的完整性检查解析错误,以避免用户错误输入使用root的权限直接执行visudo,打开suders文件$visudo 注意:这里不需要输入shduers文件的路径,默认为/etc