Spring Security同时配置JWT与Basic认证的代码修改咨询
问题
我希望在Spring Security中同时使用两种不同的认证方式,具体需求如下:
/auth/**和/public/**路径:允许所有用户访问,无需认证;/api/**路径:需通过JWT认证才能访问;/orders/**路径:需通过Basic认证才能访问。
以下是我的配置文件代码:
@Configuration @EnableWebSecurity public class SecurityConfiguration { @Configuration @Order(2) @AllArgsConstructor public static class JwtWebSecurityConfig extends WebSecurityConfigurerAdapter { private final UserService userService; private final JwtRequestFilter jwtRequestFilter; private final JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint; private final PasswordEncoder passwordEncoder; @Override protected void configure(HttpSecurity http) throws Exception { http .cors() .and() .csrf().disable() .authorizeRequests() .antMatchers("/auth/**", "/public/**").permitAll() .antMatchers(HttpMethod.OPTIONS, "/api/**").permitAll() .anyRequest().authenticated() .and() .exceptionHandling() .authenticationEntryPoint(jwtAuthenticationEntryPoint) .and() .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS); http .addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class); } @Autowired @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth .userDetailsService(userService) .passwordEncoder(passwordEncoder.bCryptPasswordEncoder()); } @Bean @Override public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } } @Configuration @AllArgsConstructor @Order(1) public static class BasicAuth extends WebSecurityConfigurerAdapter { private final PasswordEncoder passwordEncoder; private final CustomBasicAuthenticationEntryPoint customBasicAuthenticationEntryPoint; @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth .inMemoryAuthentication() .withUser("admin") .password(passwordEncoder.bCryptPasswordEncoder().encode("user12345!")) .roles("ADMIN"); } @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/auth/**").permitAll() .antMatchers("/public/**").permitAll() .antMatchers("/orders/**").hasRole("ADMIN") .and() .httpBasic(); } } }
请问上述代码中哪些部分需要修改以满足需求?
需要修改的部分
1. 明确配置类的路径处理范围,避免互相干扰
当前两个配置类的路径规则存在重叠,会导致请求被错误的认证逻辑拦截。需要通过requestMatchers()指定每个配置类负责的路径,实现隔离:
修改JwtWebSecurityConfig的configure(HttpSecurity http):
添加requestMatchers()限制仅处理/api/**、/auth/**、/public/**路径,同时排除/orders/**:@Override protected void configure(HttpSecurity http) throws Exception { http .cors() .and() .csrf().disable() .requestMatchers() .antMatchers("/api/**", "/auth/**", "/public/**") .and() .authorizeRequests() .antMatchers("/auth/**", "/public/**").permitAll() .antMatchers(HttpMethod.OPTIONS, "/api/**").permitAll() .anyRequest().authenticated() .and() .exceptionHandling() .authenticationEntryPoint(jwtAuthenticationEntryPoint) .and() .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS); http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class); }修改BasicAuth的configure(HttpSecurity http):
添加requestMatchers()限制仅处理/orders/**、/auth/**、/public/**路径,同时排除/api/**,并配置自定义认证入口点:@Override protected void configure(HttpSecurity http) throws Exception { http .requestMatchers() .antMatchers("/orders/**", "/auth/**", "/public/**") .and() .authorizeRequests() .antMatchers("/auth/**", "/public/**").permitAll() .antMatchers("/orders/**").hasRole("ADMIN") .and() .httpBasic() .authenticationEntryPoint(customBasicAuthenticationEntryPoint); }
2. 修复密码编码器的重复调用问题
假设PasswordEncoder的Bean已经是BCryptPasswordEncoder类型,无需重复调用bCryptPasswordEncoder()方法:
JwtWebSecurityConfig中的认证配置修改:
@Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth .userDetailsService(userService) .passwordEncoder(passwordEncoder); }BasicAuth中的密码编码修改:
@Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth .inMemoryAuthentication() .withUser("admin") .password(passwordEncoder.encode("user12345!")) .roles("ADMIN"); }
3. 确保自定义Basic认证入口点生效
BasicAuth类中注入了CustomBasicAuthenticationEntryPoint,但原代码未在配置中使用,需要在httpBasic()后添加该配置,保证认证失败时触发自定义错误处理(已包含在上面的BasicAuth配置修改中)。
内容的提问来源于stack exchange,提问作者Oğuzhan Erçelik
相关产品推荐
相关产品推荐

