Spring Security
Spring Security借助一系列Servlet Filter来提供各种安全性功能。DelegatingFilterProxy是一个特殊的Servlet Filter,它本身所做的工作并不多。只是将 工作委托给一个javax.servlet.Filter实现类,这个实现类作为一个注册在 Spring应用的上下文中。
java的配置如下
package spittr.config;
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
public class SecurityWebInitializer extends AbstractSecurityWebApplicationInitializer {
}
AbstractSecurityWebApplicationInitializer实现了 WebApplicationInitializer,因此Spring会发现它,并用它在Web容器中注册 DelegatingFilterProxy。将请求委托给ID 为springSecurityFilterChain bean。
编写安全性配置
@EnableWebMvcSecurity可以启用任意Web应用的安全性功能,还配置了一个Spring MVC参数解析 解析器(argument resolver)
@Configuration
@EnableWebMvcSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(xxx) throws Exception {}
...
}
为了让Spring Security满足我们应用的需求,还需要再添加一点配置。
基于各种数据存储来认证用户
(1)基于内存的用户存储
对于调试和开发人员测试来讲,基于内存的用户存储是很有用的,但是对于生产级别的应用 来讲,这就不是最理想的可选方案了。为了用于生产环境,通常最好将用户数据保存在某种 类型的数据库之中。
下面的配置用withUser()方法为内存用户存储添加新的用户
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
}
(2)基于数据库表进行认证
用户数据通常会存储在关系型数据库中,并通过JDBC进行访问。为了配置Spring Security使 用以JDBC为支撑的用户存储,我们可以使用jdbcAuthentication()方法,所需的最少 配置如下所示:
@Autowired
DataSource dataSource
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.jdbcAuthentication()
.dataSource(dataSource);
}
DataSource是通过自动装配的技巧得到的。
或者也可以自定义查询
@Autowired
DataSource dataSource
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.jdbcAuthentication()
.dataSource(dataSource)
.usersByUsernameQuery(
"selcet username, password, true "+ "from Spitter where username=?")
.passwordEncoder(new StandardPasswordEncoder("pasword"))
}
数据库中的密码是永远不会解码的。 所采取的策略与之相反,用户在登录时输入的密码会按照相同的算法进行转码,然后再与数 据库中已经转码过的密码进行对比。这个对比是在PasswordEncoder的matches()方法 中进行的。
(3)配置自定义的用户服务
设我们需要认证的用户存储在非关系型数据库中,如Mongo或Neo4j,在这种情况下,我 们需要提供一个自定义的UserDetailsService接口实现。
public interface UserDetailsService{
UserDetails loadUserByUsername(String username) throws UsernameNotFoundException{
}
}