方法安全

从2.0版本开始Spring Security 改进了对服务层方法的安全支持,它提供了对JSR-250注解安全支持以及框架的原生@Secured注解的支持。从3.0开始你也可以使用新的基于表达式的注解。你可以将安全应用到单个bean.使用intercept-methods元素装饰Bean的声明。或者你可以在使用AspectJ风格的切入点应用安全到整个服务层的多个Bean类。

<global-method-security> 元素

这个元素用来在你的应用程序中启用基于注解的安全性(通过设置元素的appropriate属性),同时分组将应用到整个应用程序上下文的安全切入点声明。你应该只定义一个<global-method-security>元素。下面的定义可以开启Spring Security的@Secured支持:

  1. <global-method-security secured-annotations="enabled" />

添加一个注解到类或者接口的方法中可以限制对相应方法的访问。Spring Security的原生注解支持定义了一套用于该方法的属性。这些将被传递到AccessDecisionManager用来做实际的决定:

  1. public interface BankService {
  2. @Secured("IS_AUTHENTICATED_ANONYMOUSLY")
  3. public Account readAccount(Long id);
  4. @Secured("IS_AUTHENTICATED_ANONYMOUSLY")
  5. public Account[] findAccounts();
  6. @Secured("ROLE_TELLER")
  7. public Account post(Account account, double amount);
  8. }

启用 JSR-250 注解使用

  1. <global-method-security jsr250-annotations="enabled" />

这些都是基于标准的,并允许应用简单的基于角色的约束,但是没有Spring Security的原生注解强大。要使用新的基于表达式的语法,你可以使用

  1. <global-method-security pre-post-annotations="enabled" />

等价的Java代码如下

  1. public interface BankService {
  2. @PreAuthorize("isAnonymous()")
  3. public Account readAccount(Long id);
  4. @PreAuthorize("isAnonymous()")
  5. public Account[] findAccounts();
  6. @PreAuthorize("hasAuthority('ROLE_TELLER')")
  7. public Account post(Account account, double amount);
  8. }

基于表达式的注解是一个很好的选择,如果你需要定义超过一个检查当前用户列表中的角色名称的简单的规则。

被注解的方法将仅在被定于为Spring 的Bean的实例时才能确保安全(在相同的应用程序的上下文中该方法-启用方法安全检查)。如果你想确保非Spring创建的实例的安全性(比如使用new操作符创建的),那么你需要使用AspectJ。

你可以在同一个应用程序中启用多种注解,但是在一个接口或者类中只能使用一种类型的注解,否则会出现不明确的行为。如果对特定的方法使用了两个注解,只有其中的一个会被应用。

使用protect-pointcut添加切入点保护

  1. ```xml
  2. <global-method-security>
  3. <protect-pointcut expression="execution(* com.mycompany.*Service.*(..))"
  4. access="ROLE_USER"/>
  5. </global-method-security>

这将保护在应用程序上下文定义的所有在com.mycompany包下类名以”Service”结尾的类的方法。只有拥有ROLE_USER角色用户才能执行这些方法。和URL匹配一样,列表中多个匹配的话将会使用第一个匹配的. 安全注解比切入店有更高的优先级。