Striveonger

vuePress-theme-reco Mr.Lee    2015 - 2025
Striveonger Striveonger
主页
分类
  • 文章
  • 笔记
  • 工具
标签
时间轴
author-avatar

Mr.Lee

266

Article

136

Tag

主页
分类
  • 文章
  • 笔记
  • 工具
标签
时间轴

重开 Spring Security

vuePress-theme-reco Mr.Lee    2015 - 2025

重开 Spring Security

Mr.Lee 2021-06-24 19:16:23 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>
1
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"));
    }
}
1
2
3
4
5
6
7
8

这个配置开启了一个HTTP Basic类型的认证, 所有服务的访问都必须先过这个认证, 默认的用户名为user, 密码由Sping Security自动生成, 回到IDE的控制台, 可以找到密码信息:

Using default security password: e9ed391c-93de-4611-ac87-d871d9e749ac
1

但是自动生成的密码, 每次项目重启, 都会刷新. 我们尝试在application.yml 中配置一下用户名和密码:

spring:
  security:
    user:
      name: striveonger
      password: 123456
1
2
3
4
5

尝试用Basic方式访问: http://striveonger:123456@localhost:8080/hello, 可看到是可以正常访问的:

image-20210625104643672

当Spring项目中引入了Spring Security依赖的时候, 默认会开启Basic配置:

security:
  basic:
    enabled: true
1
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();
    }
}
1
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表单的方式了:

image-20210625143952384

我们可以看到, 在访问 http://localhost:8080/hello 时, 被重定向到了 http://localhost:8080/login.html

如果用户或密码出错会跳转到 http://localhost:8080/login.html?error

# 基本原理

image-20210628155555714

# 登录过程

  1. 通过UsernamePasswordAuthenticationFilter 获取到参数中的用户名与密码

image-20210628161422311

  1. 创建ProviderManaager

image-20210628162027913

  1. 开始用Provider校验用户名和密码

image-20210628162458723

  1. 验证用户名的有效性

image-20210628163115265

image-20210625165801182

  1. 开始验证密码的正确性

image-20210628163549476

参考文章:

  • https://mrbird.cc/Spring-Boot&Spring-Security.html