Spring学习笔记之保护方法应用
来源:互联网 发布:一物降一物 知乎 编辑:程序博客网 时间:2024/06/06 01:41
在本章中我们将会看到如何使用Spring Security保护bean方法。
1.使用注解保护方法
在Spring Security中实现方法级安全性的最常见办法是使用特定的注解,将这些注解应用到需要保护的方法上。这样有几个好处,最重要的是当我们在编辑器中查看给定的方法时,能够很清楚地看到它的安全规则。
Spring Security提供了三种不同的安全注解:
- Spring Security自带的@Security注解
- JSR-250的@RolesAllowed注解
- 表达式驱动的注解,包括@PreAuthorize,@PostAuthorize,@PreFilter,@PostFilter。
1.1使用@Secured注解限制方法调用
在Spring中,如果要启用基于注解的方法安全性,关键之处在于要在配置类上使用@EnableGlobalMethodSecurity:
@Configuration@EnableGlobalMethodSecurity(securedEnabled=true)public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration{}
GlobalMethodSecurityConfiguration类能够为方法级别的安全性提供更精细的配置。
如果securedEnabled属性的值为true的话,将会创建一个切点,这样的话Spring Security切面就会包装带有@Security注解的方法。(所以最好把要控制权限的方法放在service层)。
示例:
@Servicepublic class SecurityService { @Secured("ROLE_ADMIN") public void test1(){ System.out.println("拥有ADMIN权限"); } @Secured({"ROLE_ADMIN","ROLE_USER"}) public void test2(){ System.out.println("拥有ADMIN或USER权限"); }}
@Secured注解的不足之处在于它是spring特定的注解。如果更倾向于使用Java标准定义的注解,那么你应该考虑使用@RolesAllowed注解
1.2在Spring Security中使用JSR-250的@RolesAllowed注解
@RolesAllowed是JSR-250定义的Java标准注解。如果选择@RolesAllowed的话,需要将@EnableGlobalMethodSecurity的jsr250Enabled属性设置为true,以开启此功能:
@Configuration@EnableGlobalMethodSecurity(securedEnabled=true,jsr250Enabled=true)public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration{}
使用示例:
@Servicepublic class SecurityService { @RolesAllowed("ROLE_ADMIN") public void test1(){ System.out.println("拥有ADMIN权限"); } @RolesAllowed({"ROLE_ADMIN","ROLE_USER"}) public void test2(){ System.out.println("拥有ADMIN或USER权限"); }}
2.使用表达式实现方法级别的安全性
Spring Security 3.0提供了4个新的注解,可以使用SpEL表达式来保护方法调用
首先,我们需要将@EnableGlobalMethodSecurity的prePostEnabled属性值设为true,从而开启它们:
@Configuration@EnableGlobalMethodSecurity(securedEnabled=true,jsr250Enabled=true,prePostEnabled=true)public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration{}
2.1表述方法访问规则
@PreAuthorize和@PostAuthorize能够基于表达式的计算结果来限制方法的访问。区别在于表达式执行的时机。@PreAuthorize的表达式会在方法调用之前执行,如果表达式的计算结果不为true的话,将会阻止方法执行。与之相反,@PostAuthorize的表达式知道方法返回才会执行,然后根据结果决定是否抛出安全性异常,如果为false,会抛出一个AccessDeniedException异常,而调用者也得不到返回的值。
@Servicepublic class SecurityService { @PreAuthorize("hasRole('ROLE_ADMIN') and #num > 5") public void test1(int num){ System.out.println("拥有ADMIN权限并且输入的数字大于5"); } @PostAuthorize("returnObject == 'abc'") public String test2(){ System.out.println("执行方法并返回一个字符串对象"); return "abcd"; }}
为了便利地访问受保护方法的返回对象,Spring Security在SpEL中提供了名为returnObject的变量。
2.2 过滤方法的输入和输出
@PostFilter和@PreFilter都使用一个SpEL作为值参数,但是这个表达式不是用来限制方法访问的,@PostFilter会使用这个表达式计算该方法所返回集合的每个成员,将计算结果为false的成员从结果集中除掉,返回结果集。而@PreFilter过滤的是要进入方法中的集合,同样会对每一条数据进行检查,只有满足表达式(即表达式返回true)的结果才能保留在集中,最终传到方法里面。
@Servicepublic class SecurityService { /** * 需要拥有ADMIN或USER权限才能访问, * ADMIN缺陷的话返回所有数据, * USER权限的话只返回和登录用户相同用户名的数据 * @return */ @PreAuthorize("hasAnyRole({'ROLE_ADMIN','ROLE_USER'})") @PostFilter("hasRole('ROLE_ADMIN') || " + "filterObject.username == principal.username") public List<User> test1(){ User u1 = new User("xuexiaoqiang"); User u2 = new User("admin"); User u3 = new User("xueqiang"); List<User> list = new ArrayList<User>(); list.add(u1); list.add(u2); list.add(u3); return list; } /** * 需要拥有ADMIN或USER权限才能访问, * 拥有ADMIN权限的用户会将数据全部传入方法中 * 拥有USER权限的用户只会将相同用户名的数据传进去 * @param users */ @PreAuthorize("hasAnyRole({'ROLE_ADMIN','ROLE_USER'})") @PreFilter("hasRole('ROLE_ADMIN') || " + "filterObject.username == principal.username") public void test2(List<User> users){ for(User u : users){ System.out.println(u.getUsername()); } }}
filterObject对象引用的是传入或传出的List中的某一个元素。
- Spring学习笔记之保护方法应用
- SpringInAction学习笔记——第14章 保护方法应用
- 保护Spring应用之——spring Security(一)
- 保护Spring应用之——spring Security(二)
- 05.Spring Cloud学习笔记之服务容错保护组件Hystrix
- SpringSecurity学习笔记之六:保护视图
- 《pro Spring》学习笔记之Spring HTTP 远程方法调用
- 第9章 保护Web应用--Spring Security 之 HelloWord
- 学习笔记之Spring
- 使用shrio保护spring 应用
- 《Pro Spring》学习笔记之生命周期init初始化方法
- 《Pro Spring》学习笔记之Method Replacement(方法替换)
- 操作系统学习笔记:保护
- [学习笔记] KEIL 下保护部分代码方法。
- 《pro Spring》学习笔记之Spring HTTP 远程方法调用返回复杂类型的方法
- Spring注解方法学习笔记
- spring security:保护方法调用
- 学习笔记:一个操作系统的实现--保护模式之基础知识
- C++/MFC-多线程绘图
- 对于一个矩阵,请设计一个算法从左上角(mat[0][0])开始,顺时针打印矩阵元素。 给定int矩阵mat,以及它的维数nxm,请返回一个数组,数组中的元素为矩阵元素的顺时针输出。
- Spring(一)--控制反转
- 《Linux CAN编程详解》
- mysql数据库
- Spring学习笔记之保护方法应用
- [杜教筛] BZOJ 4916 神犇和蒟蒻
- 剑指offer-合法的出栈序列
- 38 C语言自增(++)和自减(--)
- 微博分享sdk4.0 中遇到的坑以及解决办法汇总
- SPOJ DIVCNT2(莫比乌斯反演+杜教筛)
- 在微服务的世界里, 你应该要知道的几件事
- 数据库复习(1)--MySQL复制表结构和数据
- Linux脚本学习攻略笔记16