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

CustomAuthenticationProvider的authenticate被调用两次问题求助(已参考相关帖)

Troubleshooting Duplicate authenticate Calls with Empty Password on Second Attempt

Hey there, let's break down this frustrating double authentication call issue you're dealing with. You mentioned referencing comments under the post ProviderManager.authenticate called twice for BadCredentialsException but still hitting the same problem—where authenticate gets triggered twice, with valid credentials on the first call and an empty password on the second. Let's walk through likely causes and fixes:

Common Root Causes

  • Outdated Security Configuration Conflicts: If you're still using UserWebSecurityConfigurerAdapter (deprecated in Spring Boot 2.7+), it might clash with Spring's auto-configured SecurityFilterChain, leading to duplicate request processing.
  • Accidental Credential Erasure: Spring Security defaults to erasing credentials after successful authentication. If a secondary process triggers re-authentication, it might be working with already-cleared credentials.
  • Misconfigured ProviderManager/Multiple Providers: If your setup has multiple registered providers or the ProviderManager is set to retry on exception, it could trigger a second call even when the first attempt had valid credentials.
  • Frontend Request Duplication: While less likely given the empty password, a misconfigured frontend (like an undisabled submit button leading to double clicks) could send two requests—though the second would usually carry the same credentials unless there's a form reset issue.

Step-by-Step Fixes & Debugging

1. Update to Modern Security Configuration

Replace the deprecated WebSecurityConfigurerAdapter with SecurityFilterChain to avoid auto-config conflicts:

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                .anyRequest().authenticated()
            )
            .formLogin(form -> form
                .loginProcessingUrl("/login") // Match your form's action URL
                .permitAll()
            );
        return http.build();
    }

    @Bean
    public CustomAuthProvider customAuthProvider() {
        return new CustomAuthProvider();
    }
}

2. Add Detailed Logging to Trace the Second Call

Insert logging in your CustomAuthProvider to pinpoint where the second call is coming from, including credential state and call stack:

@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
    String username = authentication.getName();
    String password = (String) authentication.getCredentials();
    
    // Log credential state
    System.out.println("Auth triggered for user: " + username 
        + " | Password present? " + (password != null && !password.isBlank()));
    
    // Log full call stack to trace origin
    new RuntimeException("Authentication Call Stack").printStackTrace();

    // Your existing validation logic
    if (!isValidCredentials(username, password)) {
        throw new BadCredentialsException("Invalid credentials");
    }

    return new UsernamePasswordAuthenticationToken(username, password, Collections.emptyList());
}

The stack trace will show exactly which part of your code/Spring Security is initiating the second call.

3. Disable Credential Erasure (If Needed)

If the second call is using cleared credentials, disable credential erasure in your provider configuration:

// For legacy setups using WebSecurityConfigurerAdapter
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.authenticationProvider(customAuthProvider())
        .eraseCredentials(false); // Preserve credentials post-authentication
}

4. Check for Duplicate Configuration Classes

Ensure you don't have multiple @Configuration classes handling Spring Security—this can lead to overlapping filter chains that process the same request twice.

5. Validate Frontend Request Flow

Inspect your frontend code to confirm the login form isn't submitting twice (e.g., button not disabled after first click) or resetting the password field before a second submission. You can also check browser network logs to see if two requests are being sent, and what payload they carry.

Final Notes

Once you've traced the second call's origin with the stack trace, you can target the exact issue—whether it's a config conflict, unintended retry logic, or frontend behavior.

内容的提问来源于stack exchange,提问作者jw-at

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:16:59