tonglin0325的个人主页

SpringBoot学习笔记——spring security

Spring Security是提供了认证,鉴权以及其他的安全特性的java框架,下面是Spring Security的使用教程

1.引入依赖

1
2
3
4
5
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>

引入依赖用会发现请求所有的接口都会跳转到 /login,要求你进行账号密码的认证

 

其默认的用户是user,密码会在日志中打印出来,Using generated security password: xxxxxxxx

账号密码正确后,接口就可以正常请求,且一般情况下同一个电脑同一个浏览器下的session是共享的,比如同个浏览器下多个窗口的session id是相同的

如果想自定义认证的方式的话,可以通过继承 WebSecurityConfigurerAdapter 的方式,重写configure(HttpSecurity http) 方法

不添加的话,默认的配置等于:使用fromLogin()表单方式对所有的request进行httpBasic()账号密码认证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

@Override
public void configure(HttpSecurity http) throws Exception {

http
.authorizeRequests()
.anyRequest().authenticated()
.and().formLogin()
.and().httpBasic();
}
}

如果需要添加自定义账号密码,可以通过重写configure(final AuthenticationManagerBuilder auth) 方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}

@Override
public void configure(final AuthenticationManagerBuilder auth) throws Exception {

auth
.inMemoryAuthentication()
.withUser("admin")
.password(this.passwordEncoder().encode("admin"))
.roles("USER");
}

@Override
public void configure(HttpSecurity http) throws Exception {

http
.authorizeRequests()
.antMatchers(HttpMethod.GET, "/login").permitAll()
.anyRequest().authenticated()
.and().formLogin()
.and().httpBasic();
}

}

这时对非/login的请求,都需要进行认证

需要注意的是,对于POST请求,添加了认证之后,仍然会报403,需要额外关闭csrf

1
2
3
4
http
// 关闭csrf
.csrf().disable();

参考:spring boot post请求403,get请求成功

Security关闭CSRF

可以在添加自定义 filter 来实现基于web token的认证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import com.example.demo.jwt.JwtAuthenticationFilter;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.annotation.Resource;

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

@Resource
private JwtAuthenticationFilter jwtAuthenticationFilter;

@Override
public void configure(HttpSecurity http) throws Exception {

http
.authorizeRequests()
.anyRequest().authenticated();

http
.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);

}
}

自定义filter,JwtAuthenticationFilter,在其中对