依賴引入
<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