重开 Spring Security
Spring Security是一款基于Spring的安全框架, 主要包含认证和授权两大安全模块, 和另外一款流行的安全框架Apache Shiro相比, 它拥有更为强大的功能. Spring Security也可以轻松的自定义扩展以满足各种需求, 并且对常见的Web安全攻击提供了防护支持. 如果你的Web框架选择的是Spring, 那么在安全方面Spring Security会是一个不错的选择.
这里我们使用Spring Boot来集成Spring Security, Spring Boot版本为2.3.0.RELEASE
, Spring Security版本为5.3.2.RELEASE
.
# 开启Spring Security
创建一个Spring Boot项目, 然后引入spring-boot-starter-security:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
2
3
4
接下来我们创建一个TestController, 对外提供一个/hello
服务:
@RestController
public class TestController {
@GetMapping("/hello")
public Map<String, Object> hello() {
return Dict.of(Pair.of("status", "ok"), Pair.of("message", "Hello"));
}
}
2
3
4
5
6
7
8
这个配置开启了一个HTTP Basic类型的认证, 所有服务的访问都必须先过这个认证, 默认的用户名为user
, 密码由Sping Security自动生成, 回到IDE的控制台, 可以找到密码信息:
Using default security password: e9ed391c-93de-4611-ac87-d871d9e749ac
但是自动生成的密码, 每次项目重启, 都会刷新. 我们尝试在application.yml
中配置一下用户名和密码:
spring:
security:
user:
name: striveonger
password: 123456
2
3
4
5
尝试用Basic方式访问: http://striveonger:123456@localhost:8080/hello, 可看到是可以正常访问的:
当Spring项目中引入了Spring Security依赖的时候, 默认会开启Basic配置:
security:
basic:
enabled: true
2
3
# 基于表单认证
我们可以通过一些配置将HTTP Basic认证修改为基于表单的认证方式。
创建一个配置类WebSecurityConfig
继承org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
这个抽象类并重写configure(HttpSecurity http)
方法. WebSecurityConfigurerAdapter
是由Spring Security提供的Web应用安全配置的适配器:
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
// 为login添加许可
.antMatchers("/login", "/login.html").permitAll()
// 验证所有请求
.anyRequest().authenticated()
.and()
// 允许用户使用表单登录进行身份认证
.formLogin()
.loginProcessingUrl("/login")
.loginPage("/login.html").permitAll()
.and()
// 允许用户使用HTTP基本认证(Basic认证方式与Form认证方式共存)
.httpBasic();
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Spring Security提供了这种链式的方法调用. 上面配置指定了认证方式为form表单登录和Basic登录, 并且所有请求都需要进行认证.
这时候我们重启项目, 再次访问http://localhost:8080/hello, 可以看到认证方式已经是form表单的方式了:
我们可以看到, 在访问 http://localhost:8080/hello 时, 被重定向到了 http://localhost:8080/login.html
如果用户或密码出错会跳转到 http://localhost:8080/login.html?error
# 基本原理
# 登录过程
- 通过
UsernamePasswordAuthenticationFilter
获取到参数中的用户名与密码
- 创建ProviderManaager
- 开始用Provider校验用户名和密码
- 验证用户名的有效性
- 开始验证密码的正确性
参考文章:
- https://mrbird.cc/Spring-Boot&Spring-Security.html