无法覆盖Spring Security对REST API的默认Basic认证问题
看起来你遇到的问题主要来自三个核心点:配置类不完整、Spring未扫描到你的自定义配置类,以及缺少密码编码器(Spring Security 5+的强制要求)。咱们一步步来解决:
1. 补全你的Security配置类
你粘贴的SecurityConfiguration代码是不完整的,这直接导致Spring无法加载你的自定义规则。在Spring Boot 2.x版本中,自定义Security配置需要继承WebSecurityConfigurerAdapter,并重写核心配置方法。这里给你一个完整的可运行示例:
package com.worldline.config; import org.springframework.context.annotation.Configuration; 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.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; @Configuration @EnableWebSecurity // 必须添加此注解启用自定义Security配置 public class SecurityConfiguration extends WebSecurityConfigurerAdapter { // 提供密码编码器,Spring Security 5+强制要求密码必须加密 private PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { // 配置自定义的内存用户认证信息 auth.inMemoryAuthentication() .passwordEncoder(passwordEncoder()) .withUser("custom-user") // 你的自定义用户名 .password(passwordEncoder().encode("custom-pass")) // 你的自定义密码(需加密) .roles("USER"); } @Override protected void configure(HttpSecurity http) throws Exception { // 启用Basic认证,保护所有接口 http.csrf().disable() // REST接口通常关闭CSRF防护 .authorizeRequests() .anyRequest().authenticated() .and() .httpBasic(); } }
2. 确保Spring能扫描到你的配置类
你的Application类在com.worldline.rest包下,而SecurityConfiguration在com.worldline.config包下。默认情况下,@SpringBootApplication的组件扫描仅覆盖当前包(com.worldline.rest)及其子包,所以com.worldline.config不在扫描范围内——Spring根本没加载你的自定义配置,自然会沿用默认规则!
解决方法二选一:
- 方法一:修改Application类的扫描范围
取消你注释的@ComponentScan,指定要扫描的包集合:
package com.worldline.rest; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.ComponentScan; @ComponentScan({"com.worldline.rest", "com.worldline.config"}) // 同时扫描业务包和配置包 @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
- 方法二:调整配置类的包结构
把SecurityConfiguration移到com.worldline.rest.config包下(作为Application所在包的子包),这样默认扫描就能覆盖到,无需额外配置@ComponentScan。
3. 关于密码编码器的说明
Spring Security 5之后,彻底禁止了明文密码的使用(除非手动开启不安全的配置,不推荐)。所以必须为你的用户密码指定编码器,示例中用的BCryptPasswordEncoder是工业级的加密方式,如果你只是测试,可以临时用NoOpPasswordEncoder(但生产环境绝对不能用)。
最后验证
完成以上修改后,重启应用,用你配置的自定义用户名和密码访问/greeting,应该就能正常访问了——不会再出现默认的user/启动时生成的密码,也不会再收到"Bad credentials"提示。
内容的提问来源于stack exchange,提问作者Sunny

