Spring Security OAuth 已经不推荐使用了,最新的OAuth 2.0 的支持由Spring Security提供,官方给出了迁移指南 http://OAuth 2.0 Migration Guide。文档还是摆在一起的, Spring Security 大类里面也有 Spring Security OAuth 的文档。
Spring Security是一套可定制的授权和访问控制框架,容易扩展适应需要。
架构
应用安全问题大体可归为两个,认证(Authentication)和授权(authorization )
认证(Authentication)
AuthenticationManager 是认证的主要策略接口,只有一个方法,authenticate()方法可能返回值有三种:
1.输入有效,验证通过,返回Authentication
对象 2.输入无效,验证不通过,抛出异常AuthenticationException
,此异常不需要捕获处理 3.不能确定,返回null
public interface AuthenticationManager {
Authentication authenticate(Authentication authentication)
throws AuthenticationException;
}
ProviderManager是最常用的AuthenticationManager的实现,其内部委托AuthenticationProvider
链进行处理。
受保护的资源通常逻辑上可以分组(路径匹配同一个模式,如 /api/** 的资源),每组可以拥有自己专门的AuthenticationManager,通常是ProviderManager,这些ProviderManager共享同一个parent,parent是一种全局的资源,作为所有provider的后备。
定制认证管理
Spring Security提供了一些帮助工具用于构建AuthenticationManager, AuthenticationManagerBuilder是最常用的帮助工具
配置全局AuthenticationManager的方式
@Configuration
public class ApplicationSecurity extends WebSecurityConfigurerAdapter {
... // web stuff here
@Autowired
public void initialize(AuthenticationManagerBuilder builder, DataSource dataSource) {
builder.jdbcAuthentication().dataSource(dataSource).withUser("dave")
.password("secret").roles("USER");
}
}
相比之下,使用@Override的将构建一个本地的AuthenticationManager
@Configuration
public class ApplicationSecurity extends WebSecurityConfigurerAdapter {
@Autowired
DataSource dataSource;
... // web stuff here
@Override
public void configure(AuthenticationManagerBuilder builder) {
builder.jdbcAuthentication().dataSource(dataSource).withUser("dave")
.password("secret").roles("USER");
}
}
Spring Boot提供了默认的全局AuthenticationManager
,默认的也是足够安全的,除非你需要自己定制AuthenticationManager
。
访问控制
一旦认证成功,便可授权访问了,访问控制的核心策略接口AccessDecisionManager,它有三个实现,最后都是委托给AccessDecisionVoter
实例,有点像ProviderManager
委托给AuthenticationProviders。
public interface AccessDecisionVoter<S> {
int ACCESS_GRANTED = 1;
int ACCESS_ABSTAIN = 0;
int ACCESS_DENIED = -1;
boolean supports(ConfigAttribute attribute);
boolean supports(Class<?> clazz);
int vote(Authentication authentication, S object,
Collection<ConfigAttribute> attributes);
}
object代表用户想访问的资源,attributes是对object的修饰。大部分情况使用默认的AccessDecisionManager,即AffirmativeBased(任意一个vote返回肯定,便可访问资源)。
Web Security
在web中Spring Security是基于Servlet Filters。客户端发送请求,容器根据uri决定应用哪个Filter和Servlet。最多只有一个Servlet处理请求,但Filter是一个有序链条,可以终止向下,可以修改请求和响应,所以Filter顺序至关重要。
v3.1开始FilterChainProxy配置SecurityFilterChain链条,用来匹配请求。
自定义过滤器链
@Configuration
@Order(SecurityProperties.BASIC_AUTH_ORDER - 10)
public class ApplicationConfigurerAdapter extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/match1/**")
...;
}
}
请求匹配和授权
@Configuration
@Order(SecurityProperties.BASIC_AUTH_ORDER - 10)
public class ApplicationConfigurerAdapter extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/match1/**")
.authorizeRequests()
.antMatchers("/match1/user").hasRole("USER")
.antMatchers("/match1/spam").hasRole("SPAM")
.anyRequest().isAuthenticated();
}
}
参考: