Spring Boot 3:JWT与Basic Auth共存后Basic Auth访问401问题
问题解决:Spring Boot 3中Basic Auth认证401未授权
核心原因
你的ExtWebSecurityConfig存在两个关键疏漏:
- 未明确限定配置仅作用于
/ext/**路径,导致Spring Security的规则匹配逻辑混乱 - 未正确配置Basic Auth所需的用户认证源(UserDetailsService)和密码编码器,导致提交的凭证无法被验证
修正后的完整配置
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.web.SecurityFilterChain; @Configuration @Order(1) public class ExtWebSecurityConfig { @Bean public SecurityFilterChain extSecurityFilterChain(HttpSecurity http) throws Exception { // 仅对/ext/**路径应用当前Basic Auth配置 http.securityMatcher("/ext/**") .authorizeHttpRequests(auth -> auth .anyRequest().authenticated() ) .httpBasic(httpBasic -> httpBasic.realmName("Ext API Realm")) .csrf(AbstractHttpConfigurer::disable); // Basic Auth场景下无需CSRF保护 return http.build(); } // 配置内存用户(对应你配置的admin/admin账号) @Bean public UserDetailsService extUserDetailsService() { UserDetails adminUser = User.withUsername("admin") .password(passwordEncoder().encode("admin")) .roles("ADMIN") .build(); return new InMemoryUserDetailsManager(adminUser); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } }
关键配置解释
securityMatcher("/ext/**"):这是Spring Security 5.7+推荐的路径隔离方式,确保当前配置只处理/ext/**的请求,不会和Keycloak的JWT认证规则冲突。如果没有这个配置,Spring Security会使用全局路径匹配,可能导致/ext请求被Keycloak的配置拦截。- UserDetailsService与PasswordEncoder:Spring Security不会自动读取application.yml中的账号密码,必须显式配置用户认证源。这里用内存用户示例,你也可以替换为数据库查询的实现。注意密码必须经过加密,不能直接明文存储。
- CSRF禁用:Basic Auth是无状态认证,CSRF保护对这类场景无效,禁用后可避免不必要的验证失败。
可选:从配置文件注入账号密码
如果不想硬编码账号密码,可以通过application.yml注入:
ext-api: auth: username: admin password: admin
然后修改extUserDetailsService:
import org.springframework.beans.factory.annotation.Value; // ... 其他代码 @Value("${ext-api.auth.username}") private String extUsername; @Value("${ext-api.auth.password}") private String extPassword; @Bean public UserDetailsService extUserDetailsService() { UserDetails adminUser = User.withUsername(extUsername) .password(passwordEncoder().encode(extPassword)) .roles("ADMIN") .build(); return new InMemoryUserDetailsManager(adminUser); }
验证步骤
- 发送请求时,确保请求头包含
Authorization: Basic YWRtaW46YWRtaW4=(admin/admin的Base64编码) - 查看控制台日志,如果出现
Bad credentials,检查密码是否正确加密,或者用户名是否匹配
内容的提问来源于stack exchange,提问作者stylepatrick
相关产品推荐
相关产品推荐

