从2.0开始Spring Security对服务层的方法的安全有了实质性的改善。他提供对JSR-250的注解安全支持象框架原生的@Secured注解一样好。从3.0开始你也可以使用新的基于表达式的注解。你可以应用安全到单独的bean,使用拦截方法元素去装饰Bean声明,或者你可以在整个服务层使用AspectJ风格的切入点保护多个bean。
我们可以在任何使用@Configuration
的实例上,使用@EnableGlobalMethodSecurity
注解来启用基于注解的安全性。例如下面会启用Spring 的 @Secured注解.
@EnableGlobalMethodSecurity(securedEnabled = true)
public class MethodSecurityConfig {
// ...
}
添加一个注解到一个方法(或者一个类或者接机)会限制对相应方法的访问。Spring Security的原生注解支持定义了一套用于该方法的属性。这些将被传递到AccessDecisionManager
来做实际的决定:
public interface BankService {
@Secured("IS_AUTHENTICATED_ANONYMOUSLY")
public Account readAccount(Long id);
@Secured("IS_AUTHENTICATED_ANONYMOUSLY")
public Account[] findAccounts();
@Secured("ROLE_TELLER")
public Account post(Account account, double amount);
}
使用如下代码启用JSR-250注解的支持
@EnableGlobalMethodSecurity(jsr250Enabled = true)
public class MethodSecurityConfig {
// ...
}
这些都是基于标准的,并允许应用简单的基于角色的约束,但是没有Spring Security的本地注解的能力。要使用新的基于表达式的语法,你可以使用:
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig {
// ...
}
和响应的Java代码如下:
public interface BankService {
@PreAuthorize("isAnonymous()")
public Account readAccount(Long id);
@PreAuthorize("isAnonymous()")
public Account[] findAccounts();
@PreAuthorize("hasAuthority('ROLE_TELLER')")
public Account post(Account account, double amount);
}
有时候你可能需要执行一些比@ EnableGlobalMethodSecurity
注解允许的更复杂的操作。对于这些情况,你可以扩展 GlobalMethodSecurityConfiguration确保@EnableGlobalMethodSecurity
注解出现在你的子类。例如:如果你想提供一个定制的MethodSecurityExpressionHander
,你可以使用下面的配置:
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
// ... create and return custom MethodSecurityExpressionHandler ...
return expressionHander;
}
}
关于可以被重载的方法的更多信息,请参考GlobalMethodSecurityConfiguration的java文档。