You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot 3:JWT与Basic Auth共存后Basic Auth访问401问题

问题解决:Spring Boot 3中Basic Auth认证401未授权

核心原因

你的ExtWebSecurityConfig存在两个关键疏漏:

  1. 未明确限定配置仅作用于/ext/**路径,导致Spring Security的规则匹配逻辑混乱
  2. 未正确配置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);
}

验证步骤

  1. 发送请求时,确保请求头包含Authorization: Basic YWRtaW46YWRtaW4=(admin/admin的Base64编码)
  2. 查看控制台日志,如果出现Bad credentials,检查密码是否正确加密,或者用户名是否匹配

内容的提问来源于stack exchange,提问作者stylepatrick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 18:23:07