1. 概述
这篇文章是关于Spring Security的Java配置介绍,它允许用户在不使用XML的情况下轻松配置Spring Security。
Java配置是在Spring框架的Spring 3.1版本中添加的,并在Spring 3.2版本中扩展到Spring Security,其定义在一个被注解为@Configuration
的类中。
2. Maven设置
要在Maven项目中使用Spring Security,首先需要在项目pom.xml
中添加spring-security-core
依赖:
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>5.3.3.RELEASE</version>
</dependency>
最新的版本可以在这里找到。
3. 使用Java配置Web安全
让我们从一个基本的Spring Security Java配置示例开始:
@EnableWebSecurity
public class SecurityConfig {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth)
throws Exception {
auth.inMemoryAuthentication().withUser("user")
.password(passwordEncoder().encode("password")).roles("USER");
}
}
你可能已经注意到,配置设置了一个基于内存的简单身份验证配置。此外,从Spring 5开始,我们还需要一个PasswordEncoder
bean:
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
4. HTTP安全
要在Spring中启用HTTP安全,我们需要创建一个SecurityFilterChain
bean:
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest().authenticated()
.and().httpBasic();
return http.build();
}
上述配置确保了应用程序的所有请求都通过表单登录或HTTP基本认证进行身份验证。
这与以下XML配置完全相同:
<http>
<intercept-url pattern="/**" access="isAuthenticated()"/>
<form-login />
<http-basic />
</http>
5. 表单登录
有趣的是,Spring Security会根据启用的功能自动生成登录页面,并使用处理提交登录的默认URL:
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest().authenticated()
.and().formLogin()
.loginPage("/login").permitAll();
return http.build();
}
这里自动生成的登录页面方便快速上手。
6. 使用角色进行授权
现在,让我们配置一些简单的角色授权,以针对每个URL:
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/", "/home").access("hasRole('USER')")
.antMatchers("/admin/**").hasRole("ADMIN")
.and()
// some more method calls
.formLogin();
return http.build();
}
请注意,我们如何同时使用类型安全API(hasRole
)和表达式基础API(access
)。
7. 注销
如同Spring Security的许多其他方面,注销也提供了框架提供的良好默认功能。
默认情况下,注销请求会清除会话、清除任何身份验证缓存、清空SecurityContextHolder
并重定向到登录页面。
这是一个简单的注销配置:
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.logout();
return http.build();
}
然而,如果你想对可用处理器有更多的控制,完整的实现将如下所示:
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.logout().logoutUrl("/my/logout")
.logoutSuccessUrl("/my/index")
.logoutSuccessHandler(logoutSuccessHandler)
.invalidateHttpSession(true)
.addLogoutHandler(logoutHandler)
.deleteCookies(cookieNamesToClear)
.and()
// some other method calls
return http.build();
}
8. 身份验证
让我们看看另一种使用Spring Security进行身份验证的方式。
8.1. 内存身份验证
我们从一个简单的内存配置开始:
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth)
throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password(passwordEncoder().encode("password")).roles("USER")
.and()
.withUser("admin").password(passwordEncoder().encode("password")).roles("USER", "ADMIN");
}
8.2. JDBC身份验证
要迁移到JDBC,你只需要在应用中定义一个数据源,并直接使用它:
@Autowired
private DataSource dataSource;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth)
throws Exception {
auth.jdbcAuthentication().dataSource(dataSource)
.withDefaultSchema()
.withUser("user").password(passwordEncoder().encode("password")).roles("USER")
.and()
.withUser("admin").password(passwordEncoder().encode("password")).roles("USER", "ADMIN");
}
当然,在这两个示例中,我们也需要像第3部分中所述那样定义PasswordEncoder
bean。
9. 总结
在这篇快速教程中,我们概述了Spring Security的Java配置基础知识,并重点介绍了展示最简单配置场景的代码示例。