Spring Security如何加密application.properties密码并支持明文认证
配置文件密码加密实现方案
报错根因
- 注册
PasswordEncoder类型Bean后,Spring Security会默认将spring.security.user.password的配置值识别为已加密的密文,不会自动对配置中的明文执行加密操作。 - 你当前配置中填写的是明文
alice,不符合BCrypt密文的格式规则(BCrypt密文固定以$2a$/$2b$/$2y$开头),校验时直接抛出Encoded password does not look like BCrypt异常,最终返回401未授权。
实现方式
方式一:配置文件直接存储密文(生产推荐)
这是最符合Spring Security设计逻辑的方案,流程如下:
- 提前生成明文密码对应的BCrypt密文,可通过测试代码生成:
@SpringBootTest public class PasswordGenerator { @Test void generateBCryptPwd() { BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(10); // 传入你的明文密码,输出对应密文 String encoded = encoder.encode("alice"); System.out.println(encoded); } }
- 将生成的密文替换到配置文件中,替换原有明文:
spring: security: user: name: bob # 替换为你实际生成的密文,以下为示例值 password: $2a$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy
- 放开配置类中注释掉的
PasswordEncoderBean即可:
@Configuration @EnableWebSecurity public class BasicAuthConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .authorizeRequests(authorize -> authorize .anyRequest().authenticated() ) .httpBasic(); return http.build(); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(10); } }
配置完成后重启服务,客户端使用原始明文凭证(用户名bob、密码alice)发起Basic认证即可正常通过,框架会自动对请求传入的明文密码做加密,和配置中存储的密文做比对校验。
方式二:自定义用户加载逻辑(适合本地测试)
如果不想提前生成密文,希望直接在配置中写明文、由代码启动时自动加密加载,可以自定义UserDetailsService实现显式处理:
- 配置文件保持明文配置不变:
spring: security: user: name: bob password: alice
- 修改安全配置类,注入配置值,启动时手动完成密码加密后加载用户信息:
@Configuration @EnableWebSecurity public class BasicAuthConfig { @Value("${spring.security.user.name}") private String username; @Value("${spring.security.user.password}") private String rawPassword; @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .authorizeRequests(authorize -> authorize .anyRequest().authenticated() ) .httpBasic(); return http.build(); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(10); } @Bean public UserDetailsService userDetailsService(PasswordEncoder passwordEncoder) { UserDetails user = User.withUsername(username) // 显式调用encode方法对配置中的明文密码加密 .password(passwordEncoder.encode(rawPassword)) .roles("USER") .build(); return new InMemoryUserDetailsManager(user); } }
注意:该方案仅适用于本地快速测试场景。生产环境不建议在配置文件中存储明文密码,也不推荐使用内存用户存储,应当对接持久化存储(如数据库),在用户注册环节就完成密码加密落库。
内容的提问来源于stack exchange,提问作者tony
相关产品推荐
相关产品推荐

