Spring Security 4 使用@PreAuthorize,@PostAuthorize, @Secured, EL实现方法安全

来源:互联网 发布:网络推广学什么 编辑:程序博客网 时间:2024/06/14 02:48

原文地址: http://blog.csdn.net/w605283073/article/details/51327182 
本文探讨spring Security 4 基于@PreAuthorize, @PostAuthorize, @Secured和 Spring EL表达式的方法级的安全。

想要开启Spring方法级安全,你需要在已经添加了@Configuration注解的类上再添加@EnableGlobalMethodSecurity注解:

package com.websystique.springsecurity.configuration;  import org.springframework.beans.factory.annotation.Autowired;  import org.springframework.context.annotation.Configuration;  import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;  import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;  import org.springframework.security.config.annotation.web.builders.HttpSecurity;  import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;  import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;  @Configuration  @EnableWebSecurity  @EnableGlobalMethodSecurity(prePostEnabled = true)  public class SecurityConfiguration extends WebSecurityConfigurerAdapter {      @Autowired      public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {          auth.inMemoryAuthentication().withUser("bill").password("abc123").roles("USER");          auth.inMemoryAuthentication().withUser("admin").password("root123").roles("ADMIN");          auth.inMemoryAuthentication().withUser("dba").password("root123").roles("ADMIN","DBA");      }      @Override      protected void configure(HttpSecurity http) throws Exception {        http.authorizeRequests()          .antMatchers("/", "/home").access("hasRole('USER') or hasRole('ADMIN') or hasRole('DBA')")          .and().formLogin().loginPage("/login")          .usernameParameter("ssoId").passwordParameter("password")          .and().exceptionHandling().accessDeniedPage("/Access_Denied");      }  }  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

@EnableGlobalMethodSecurity 开启Spring Security 全局方法安全,等价的XML配置如下:

[html] view plain copy 在CODE上查看代码片派生到我的代码片 

package com.websystique.springsecurity.service;  import org.springframework.security.access.annotation.Secured;  public interface UserService {      List<User> findAllUsers();      @Secured("ROLE_ADMIN")      void updateUser(User user);      @Secured({ "ROLE_DBA", "ROLE_ADMIN" })      void deleteUser();  }  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

在上面的例子中,updateUser 方法只能被拥有ADMIN 权限的用户调用。deleteUser 方法只能够被拥有DBA 或者ADMIN 权限的用户调用。

如果有不具有声明的权限的用户调用此方法,将抛出AccessDenied异常。

如果你想指定AND(和)这个条件,我的意思说deleteUser 方法只能被同时拥有ADMIN & DBA 。但是仅仅通过使用 @Secured注解是无法实现的。

但是你可以使用Spring的新的注解@PreAuthorize/@PostAuthorize(支持Spring EL),使得实现上面的功能成为可能,而且无限制。

@PreAuthorize / @PostAuthorize 
Spring的 @PreAuthorize/@PostAuthorize 注解更适合方法级的安全,也支持Spring 表达式语言,提供了基于表达式的访问控制。

@PreAuthorize 注解适合进入方法前的权限验证, @PreAuthorize可以将登录用户的roles/permissions参数传到方法中。

@PostAuthorize 注解使用并不多,在方法执行后再进行权限验证。

所以它适合验证带有返回值的权限。Spring EL 提供 返回对象能够在表达式语言中获取返回的对象returnObject。

请参考 Common Built-In Expressions 获取支持的表达式.

现在言归正常,使用@PreAuthorize / @PostAuthorize注解

package com.websystique.springsecurity.service;  import org.springframework.security.access.prepost.PostAuthorize;  import org.springframework.security.access.prepost.PreAuthorize;  import com.websystique.springsecurity.model.User;  public interface UserService {      List<User> findAllUsers();      @PostAuthorize ("returnObject.type == authentication.name")      User findById(int id);      @PreAuthorize("hasRole('ADMIN')")      void updateUser(User user);      @PreAuthorize("hasRole('ADMIN') AND hasRole('DBA')")      void deleteUser(int id);  }  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

由于 @PreAuthorize可以使用Spring 表达式语言, 使用EL表达式可以轻易的表示任意条件. deleteUser方法 可以被拥有ADMIN & DBA角色的用户调用 .

另外,我们增加了带有@PostAuthorize注解的findById()方法。通过@PostAuthorize注解 method(User object)的返回值在Spring表达式语言中可以通过returnObject 来使用。在例子中我们确保登录用户只能获取他自己的用户对象。

上面就是@Secured, @PreAuthorize, @PostAuthorize 和EL的使用

0 0
原创粉丝点击