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