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

Spring Boot自定义SecurityFilterChain未生效问题求助

问题描述

搭建Spring Boot应用配置基础登录功能时,已添加带@Configuration和@EnableWebSecurity注解的SecurityConfig类,且包含返回SecurityFilterChain的@Bean方法,但运行时系统仍使用DefaultSecurityFilterChain,要求用控制台输出的user账号和自动生成的密码登录,自定义配置未被识别。运行时除主方法的Hello World外,无自定义配置和UserDetailsService相关的日志输出,自定义用户也无法被识别。

SecurityConfig代码

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    @Autowired
    private ArchlandsUserDetailsService userDetailsService;
    
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        System.out.println("In securityFilterChain");   
        
        http
            .csrf().disable()
            .authorizeHttpRequests((requests) -> requests
                .requestMatchers("archlands/api/**").hasRole("USER")
                .anyRequest().authenticated()
            )
            .formLogin((form) -> form
                .loginPage("/login").permitAll()
            )
            .logout((logout) -> logout.permitAll())
            .authenticationProvider(authenticationProvider());
        
        return http.build();
    }
    
    @Bean
    public AuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
        authenticationProvider.setUserDetailsService(userDetailsService);
        return authenticationProvider;
    }
}

ArchlandsUserDetailsService代码

@RequiredArgsConstructor
@Service
@Slf4j
public class ArchlandsUserDetailsService implements UserDetailsService {
    @Autowired
    private UserService userService;
    
    @Override
    public UserDetails loadUserByUsername(String username) {
        String cleanedUsername = ArchlandsInputSanitizer.clean(username);
        log.info("User " + cleanedUsername + " is attempting to access the Archlands.");
        System.out.println("User " + cleanedUsername + " is attempting to access the Archlands.");
        
        Set<GrantedAuthority> grantedAuthorities = new HashSet<>();
        UserDto user = userService.findById(cleanedUsername);
        
        if (user == null) {
            log.error("No user exists with user id: " + cleanedUsername);
            throw new UsernameNotFoundException("No user exists with user id: " + cleanedUsername);
        }
        
        if (user.getStatus().equals("Active")) {
            grantedAuthorities.add(new SimpleGrantedAuthority("ROLE_USER"));
        }
        
        for (int i = 0; i < user.getRoles().length; i++) {
            if (user.getRoles()[i].equals(Role.DM_ROLE)) {
                grantedAuthorities.add(new SimpleGrantedAuthority("ROLE_DM"));
            }
        }
        
        log.info("User: " + cleanedUsername + " has authorities: " + grantedAuthorities.toString());
        
        return new User(user.getId(), user.getPassword(), grantedAuthorities);
    }
    
}

控制台输出

控制台自动生成默认用户密码,示例如下:

Using generated security password: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
解决方案

1. 检查配置类包扫描范围

确保SecurityConfig所在包被Spring Boot主类的@SpringBootApplication注解覆盖扫描。如果主类在com.example.demo,而配置类在com.example.demo.config则默认会被扫描;若配置类在其他独立包,需在主类添加@ComponentScan(basePackages = "你的配置类包路径")指定扫描范围。

2. 为认证提供者添加密码编码器

Spring Security 5+强制要求配置密码编码器,否则DaoAuthenticationProvider不会生效,系统会 fallback到默认用户认证。修改authenticationProvider方法:

@Bean
public AuthenticationProvider authenticationProvider() {
    DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
    authenticationProvider.setUserDetailsService(userDetailsService);
    // 这里用BCrypt编码器,需和用户密码存储的加密方式匹配
    authenticationProvider.setPasswordEncoder(new BCryptPasswordEncoder());
    return authenticationProvider;
}

同时确保UserDto中存储的密码是对应编码器加密后的结果(比如BCrypt加密字符串)。

3. 修正请求匹配器路径格式

requestMatchers("archlands/api/**")缺少开头斜杠,应改为requestMatchers("/archlands/api/**"),否则路径匹配失效,安全规则无法生效。

4. 调整日志配置

确保ArchlandsUserDetailsService的日志能正常输出,在application.properties中添加:

logging.level.你的包路径.ArchlandsUserDetailsService=INFO

替换你的包路径为该类实际所在的包(比如com.example.demo.service)。

5. 验证UserService查询逻辑

检查userService.findById(cleanedUsername)是否能正确返回用户数据,若该方法始终返回null,会触发UsernameNotFoundException,但因配置未生效,不会走到这一步。可单独编写测试用例验证UserService的查询功能。

6. 强制禁用默认安全配置(可选)

若上述步骤无效,可在SecurityConfig的@EnableWebSecurity注解中添加excludeDefaults = true,强制禁用默认配置,确保自定义配置被加载:

@Configuration
@EnableWebSecurity(excludeDefaults = true)
public class SecurityConfig {
    // ... 原有代码
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 15:50:31