Spring Security自定义AuthenticationProvider authenticate方法被调用两次

uyto3xhc  于 2023-10-20  发布在  Spring
关注(0)|答案(2)|浏览(244)

我正在开发一个使用API Key进行身份验证的Sping Boot 。我已经创建了一个自定义的身份验证提供程序,并且authenticate方法被调用了两次。有人能告诉我为什么叫了两次吗?
这是我的authenticate方法:

@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
    ApiAuthenticationToken authenticationToken = (ApiAuthenticationToken) authentication;

    /**
     * Authenticate the token
     */
    ValidateApiKeyRequest request = new ValidateApiKeyRequest(authenticationToken.getApiKey());
    ValidateApiKeyResp resp = getValidateApiKeyCommand().execute(request);

    /**
     * Populate and return a new authenticaiton token
     */
    return createSuccessAuthentication(resp);
}

这是一种身份验证方法:

protected Authentication createSuccessAuthentication(final ValidateApiKeyResp resp) {
    List<GrantedAuthority> authorities = Lists.newArrayList();
    authorities.add(new SimpleGrantedAuthority("API_KEY"));
    return new ApiAuthenticationToken(resp.getApiKey(), authorities, true);
}

这是ApiAuthenticationToken构造函数:

public ApiAuthenticationToken(final ApiKey apiKey, Collection<? extends GrantedAuthority> authorities, boolean authenticated) {
    super(authorities);
    setAuthenticated(true);
    this.apiKey = apiKey;
}

这是我的安全配置:

protected void configure(HttpSecurity http) throws Exception {
    http.antMatcher(CONFIGURATION_MATCHER)
        .exceptionHandling().authenticationEntryPoint(restAuthenticationEntryPoint())
        .and()
        .addFilterBefore(apiKeyAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
        .csrf().disable()
        .authorizeRequests().antMatchers(CONFIGURATION_MATCHER).authenticated()
        .and()
        .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and()
        .authenticationProvider(apiKeyAuthenticationProvider());
j2datikz

j2datikz1#

如果其他人也有这个问题:
这个问题与我的Spring安全配置有关。我有几个用@Bean注解的方法-见下文

@Bean
public ApiKeyAuthenticationProvider apiKeyAuthenticationProvider() {
    return new ApiKeyAuthenticationProvider(getValidateApiKeyCommand());
}

@Bean
public RestAuthenticationEntryPoint restAuthenticationEntryPoint() {
    return new RestAuthenticationEntryPoint();
}

@Bean
public ApiKeyAuthenticationFilter apiKeyAuthenticationFilter() throws Exception {
    ApiKeyAuthenticationFilter apiKeyAuthenticationFilter = new ApiKeyAuthenticationFilter();
    apiKeyAuthenticationFilter.setAuthenticationManager(authenticationManagerBean());
    apiKeyAuthenticationFilter.setAuthenticationSuccessHandler(new ApiKeyAuthenticationSuccessHandler());
    apiKeyAuthenticationFilter.setAuthenticationFailureHandler(new ApiKeyAuthenticationFailureHandler());
    return apiKeyAuthenticationFilter;
}

但是这些bean在configure(HttpSecurity http)方法中再次注册。

protected void configure(HttpSecurity http) throws Exception {

    http.antMatcher(CONFIGURATION_MATCHER)
        .exceptionHandling().authenticationEntryPoint(restAuthenticationEntryPoint())
        .and()
        .addFilterBefore(apiKeyAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
        .csrf().disable()
        .authorizeRequests().antMatchers(CONFIGURATION_MATCHER).authenticated()
        .and()
        .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and()
        .authenticationProvider(apiKeyAuthenticationProvider());
}

修复方法是删除@Bean注解。现在看来很明显:)

nafvub8i

nafvub8i2#

我犯了类似的错误。当我在自定义提供程序中抛出自定义异常时,它会尝试两次身份验证。我将自定义异常的超类从AuthenticationException更改为LockedException,它解决了。我的自定义异常仍然是AuthenticationException,因为LockedException继承自AuthenticationException。

相关问题