依賴引入
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
</dependency>
啟用Spring Security
- 首先創建一個繼承
AbstractSecurityWebApplicationInitializer的類。這個操作會導致一個名為DelegatingFilterProxy的Filter被注冊,它會攔截發往應用中的請求,並將請求委托給ID為SpringSecurityFilterChain的bean
public class SecurityWebInitializer extends AbstractSecurityWebApplicationInitializer
{
}
- 再創建一個配置類
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
{
}
至此Spring Security就被啟用了,目前所有的請求都會被攔截。
配置
WebSecurityConfigurerAdapter中有三個名為configure的方法提供重載,三個方法的描述如下:
| 方法 | 描述 |
|---|---|
| configure(HttpSecurity) | 配置攔截模式 |
| configure(AuthenticationManagerBuilder) | 配置用戶信息 |
| configure(WebSecurity) | 配置Spring Security的Filter鏈 |
配置用戶信息
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
{
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception
{
auth.inMemoryAuthentication() // 基於內存的用戶存儲
.withUser("admin")
.password("password")
.roles("USER", "ADMIN");
}
配置攔截路徑
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
{
@Override
protected void configure(HttpSecurity http) throws Exception
{
http.authorizeRequests()
.antMatchers("/info").authenticated()
.antMatchers(HttpMethod.GET, "/health").hasAnyAuthority("ADMIN")
.anyRequest().permitAll();
}
}
啟用HTTPS
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
{
@Override
protected void configure(HttpSecurity http) throws Exception
{
http.authorizeRequests()
.anyRequest().permitAll()
.and()
.requiresChannel()
.antMatchers("/bankInfo").requiresSecure() // enable HTTPS
.antMatchers("/").requiresInsecure(); // disable HTTPS
}
}
禁用CSRF
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
{
@Override
protected void configure(HttpSecurity http) throws Exception
{
http.authorizeRequests()
.anyRequest().permitAll()
.and()
.csrf().disable();
}
}
登錄與注銷
- 在重寫
configure(HttpSecurity)之前會有一個默認的登錄頁面,需要登錄時會自動跳轉到這個位於/login下的頁面,但一旦重寫此方法后就會失去這個簡單的登錄頁面。
啟用默認登錄頁
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
{
@Override
protected void configure(HttpSecurity http) throws Exception
{
http.authorizeRequests()
.anyRequest().permitAll()
.and()
.formLogin();
}
}
自定義登錄頁面
如果不想做多余的配置,那么自定義的頁面里:
form的action應該提交到/login- 包含
username的輸入域且name屬性為username - 包含
password的輸入域且name屬性為password
指定URL
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
{
@Override
protected void configure(HttpSecurity http) throws Exception
{
http.authorizeRequests()
.anyRequest().permitAll()
.and()
.formLogin().loginPage("/login");
}
}
指定自定義頁面
@Configuration
@EnableWebMvc
@ComponentScan
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/login").setViewName("login");
}
}
ViewControllerRegistry可以用來直接轉發請求到一個視圖而無需編寫控制器類。
注銷
- 如果沒有啟用
CSRF,直接訪問\logout就可實現登出 - 如果啟用
CSRF,用POST方法訪問\logout並帶上CSRF Token
