Spring ecurity 5 快速体验
742字约2分钟
2024-08-08
Spring Boot
版本为 2.7.14
,我们将通过默认配置、自定义配置这两种方式进行一个 Spring Security
的快速体验
项目结构
创建一个 IndexController
,编写一个获取首页信息接口 /index/info

pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
默认配置
浏览器上输入访问接口地址 http://127.0.0.1:8080/index/info
,跳转到了登录页面

查看项目启动日志,可以看到 Using generated security password
,使用生成的 security
密码
2023-08-11 10:51:30.440 WARN 77472 --- [ main] .s.s.UserDetailsServiceAutoConfiguration :
Using generated security password: fbff3fbb-f0ed-4a0d-9c5a-b2de3782c7c9
This generated password is for development use only. Your security configuration must be updated before running your application in production.
2023-08-11 10:51:30.542 INFO 77472 --- [ main] o.s.s.web.DefaultSecurityFilterChain : Will secure any request with [org.springframework.security.web.session.
密码是有了,用户名呢?我们可以看到是 UserDetailsServiceAutoConfiguration
这个类输出的密码日志,我们直接搜索这个类看一下

进入 UserDetailsServiceAutoConfiguration
中,搜索日志中的内容 Using generated security password
,定位到日志输出的方法

可以看到密码是从 SecurityProperties.User
这个类中获取的,我们点开这个类,可以看到用户名默认为 user

输入账号 user
、密码 fbff3fbb-f0ed-4a0d-9c5a-b2de3782c7c9

登录之后,成功访问到接口

自定义配置
通过 SecurityProperties
这个类,我们可以知道 Spring Security
用户账号密码配置的前缀是 spring.security

我们在配置文件中增加如下配置,重新启动项目,启动日志中不再有 Using generated security password
日志输出
spring:
security:
user:
name: marui
password: 1234
在页面中输入账号 marui
、密码 1234
,验证通过

我们来看看为啥不打印密码日志了,在 UserDetailsServiceAutoConfiguration.getOrDeducePassword
方法中我们可以看到是通过 user.isPasswordGenerated()
来判断是否打印的
public class UserDetailsServiceAutoConfiguration {
private String getOrDeducePassword(SecurityProperties.User user, PasswordEncoder encoder) {
String password = user.getPassword();
// 密码非随机生成,则不进行密码日志打印
if (user.isPasswordGenerated()) {
logger.warn(String.format(
"%n%nUsing generated security password: %s%n%nThis generated password is for development use only. "
+ "Your security configuration must be updated before running your application in "
+ "production.%n",
user.getPassword()));
}
}
}
user.isPasswordGenerated()
直接返回 passwordGenerated
变量的值,默认就是 true
。如果我们配置了自定义的密码,那么在 setPassword()
方法中,则将 passwordGenerated
变量的值修改为了 false
,因此就不打印密码日志了
@ConfigurationProperties(prefix = "spring.security")
public class SecurityProperties {
public static class User {
private String password = UUID.randomUUID().toString();
private boolean passwordGenerated = true;
public void setPassword(String password) {
// password 为空则直接 return
if (!StringUtils.hasLength(password)) {
return;
}
// password 不为空,则设置 密码生成标识为 false
this.passwordGenerated = false;
this.password = password;
}
public boolean isPasswordGenerated() {
return this.passwordGenerated;
}
}
}