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

Spring Boot能否同时配置JWT认证与Basic认证?附现有JWT配置

Spring Boot同时支持JWT与Basic认证的实现方案

Spring Boot完全支持同时配置JWT和Basic两种认证方式,我们可以通过多HttpSecurity配置类拆分或者在同一配置中指定不同路径的认证规则来实现,以下是基于你现有代码的修改方案:

方案一:拆分多配置类(推荐,逻辑更清晰)

将原有的JWT认证配置与新增的Basic认证配置拆分为两个独立的类,通过@Order指定优先级,确保不同路径匹配对应的认证规则。

1. JWT认证配置类(处理原有接口)

@EnableWebSecurity
@Order(1) // 优先级更高,先匹配/api开头的请求
public class JwtSecurityConfigurer extends WebSecurityConfigurerAdapter {

    private JwtRequestFilter jwtRequestFilter;
    private Environment environment;
    private UserService userService;
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Autowired
    public JwtSecurityConfigurer(Environment environment, UserService userService, BCryptPasswordEncoder bCryptPasswordEncoder, JwtRequestFilter jwtRequestFilter) {
        this.environment = environment;
        this.userService = userService;
        this.bCryptPasswordEncoder = bCryptPasswordEncoder;
        this.jwtRequestFilter = jwtRequestFilter;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService).passwordEncoder(bCryptPasswordEncoder);
    }

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.csrf().disable()
                .antMatcher("/api/**") // 仅处理/api开头的请求
                .authorizeRequests()
                .antMatchers("/api/v1/users/authentication").permitAll() // 登录接口放行
                .anyRequest().authenticated()
                .and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        
        httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
        httpSecurity.cors();
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}

2. Basic认证配置类(处理WebService接口)

@EnableWebSecurity
@Order(2) // 优先级次之,处理剩余的请求(这里指定/webservice/**路径)
public class BasicAuthSecurityConfigurer extends WebSecurityConfigurerAdapter {

    private UserService userService;
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Autowired
    public BasicAuthSecurityConfigurer(UserService userService, BCryptPasswordEncoder bCryptPasswordEncoder) {
        this.userService = userService;
        this.bCryptPasswordEncoder = bCryptPasswordEncoder;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService).passwordEncoder(bCryptPasswordEncoder);
    }

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.csrf().disable()
                .antMatcher("/webservice/**") // 仅处理WebService相关路径
                .authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .httpBasic() // 启用Basic认证
                .and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        
        httpSecurity.cors();
    }
}

方案二:同一配置类中实现

如果不想拆分类,也可以在原有的SecurityConfigurer中同时配置两种认证规则,注意路径匹配的顺序(更具体的路径优先):

@EnableWebSecurity
public class SecurityConfigurer extends WebSecurityConfigurerAdapter {

    private JwtRequestFilter jwtRequestFilter;
    private Environment environment;
    private UserService userService;
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Autowired
    public SecurityConfigurer(Environment environment, UserService userService, BCryptPasswordEncoder bCryptPasswordEncoder, JwtRequestFilter jwtRequestFilter) {
        this.environment = environment;
        this.userService = userService;
        this.bCryptPasswordEncoder = bCryptPasswordEncoder;
        this.jwtRequestFilter = jwtRequestFilter;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService).passwordEncoder(bCryptPasswordEncoder);
    }

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.csrf().disable()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .cors();

        // 先配置JWT认证的路径规则
        httpSecurity.authorizeRequests()
                .antMatchers("/api/v1/users/authentication").permitAll()
                .antMatchers("/api/**").authenticated()
                .and()
                .addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);

        // 再配置Basic认证的路径规则
        httpSecurity.authorizeRequests()
                .antMatchers("/webservice/**").authenticated()
                .and()
                .httpBasic();
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}

关键说明

  • 两种认证方式复用同一个UserService和BCryptPasswordEncoder,保证用户数据一致性,无需维护两套用户体系。
  • Basic认证的请求需要在请求头中携带Authorization: Basic <base64编码的用户名:密码>,比如用户名admin、密码123456,编码后为YWRtaW46MTIzNDU2,请求头即为Authorization: Basic YWRtaW46MTIzNDU2。
  • 根据实际业务调整路径匹配规则(比如你的WebService路径不是/webservice/**,则修改对应配置)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 15:00:49