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
相关产品推荐
相关产品推荐

