首页 > 代码库 > Spring Security应用开发(17)基于方法的授权(一)评估
Spring Security应用开发(17)基于方法的授权(一)评估
Spring Security提供了4个用于方法的注解:
@PreAuthorize、@PostAuthorize、@PreFilter和@PostFilter。本文介绍前面2个注解。
@PreAuthorize
使用Spring Security的表达式来在方法执行之前控制允许执行某个方法。 如果表达式评估结果为false,则该方法不会被执行。@PreAuthorize的表达式通常是对方法的参数进行检查。
@PostAuthorize
使用Spring Security的表达式在方法执行之后控制是否允许某个方法正常返回。在该方法执行完毕后才评估表达式,如果评估结果为false,则该方法虽然被执行,但页面仍将不能正常访问。@PostAuthorize的表达式通常是对方法的返回值进行检查。
在Spring-security.xml文件中配置global-method-security结点的pre-post-annotations属性为enabled来启用方法级别的基于表达式的访问控制,以便在方法上使用上述4个注解。
<!-- 启用方法级别的基于表达式的访问控制 --> <sec:global-method-security pre-post-annotations="enabled" />
本文使用@PreAuthorize注解来控制UserService类的addUser()方法只能被zhangsan这个用户使用。
(1)UserService类:
public class UserService { @PreAuthorize("authentication.principal != null and ‘zhangsan‘ == authentication.principal.username") public void addUser(){ System.out.println("addUser called."); }
}
在@PreAuthorize注解的参数中是一个Spring 表达式,其中可以访问authentication对象,从而可以通过authentication.principal获取到当前登录的主体对象,此处为UserDetails。
如果使用zhangsan登录,则可以正常访问addUser方法,如果是其它用户,则不可以正常访问。
在这些注解的表达式中,除了可以访问Spring Security提供的hasRole()等安全表达式之外,还可以引用方法的参数,这需要使用Spring Data中提供的一个注解@Param,本文不会对此注解进行举例说明。
(2)配置UserService Bean。
<beans:bean id="userService" class="com.test.service.UserService" />
(3)在HomeController中调用UserService的方法。
private UserService userService; public UserService getUserService() { return userService; } @Resource public void setUserService(UserService userService) { this.userService = userService; } @RequestMapping("/") public ModelAndView index(){ ModelAndView mv = new ModelAndView(); mv.addObject("message", "Hello,welcome!"); mv.setViewName("home/index"); //addUser方法已进行授权控制。 this.userService.addUser(); return mv; }
(4)启用基于方法的表达式。
<!-- 启用方法级别的基于表达式的访问控制 --> <sec:global-method-security pre-post-annotations="enabled" />
(5)运行测试。
在使用zhangsan登录时,可以正常访问/home/页面。
在没有使用@PreAuthorize注解时,根据角色配置,使用wangwu访问/home页面。在使用了@PreAuthorize注解后,使用wangwu则不能正常访问。
Spring Security应用开发(17)基于方法的授权(一)评估