Skip to content

Why isn't there a simple way to set org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider#hideUserNotFoundExceptions to false? #17209

Description

@yvasyliev

Expected Behavior

I would like to have I convenient way to set org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider#hideUserNotFoundExceptions to false. An application property or bean customizer would be great.

Current Behavior

@Configuration
@Import(AuthenticationConfiguration.class)
@EnableMethodSecurity
public class SecurityConfig {
    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration authConfig) throws Exception {
        var authenticationManager = (ProviderManager) authConfig.getAuthenticationManager();
        var provider = (AbstractUserDetailsAuthenticationProvider) authenticationManager.getProviders().getFirst();
        provider.setHideUserNotFoundExceptions(false); // <-- it's quite a long way to set this property
        return authenticationManager;
    }

    @Bean
    public UserDetailsService userDetailsService() {
        return new InMemoryUserDetailsManager(new User(
                "adminId",
                "{noop}",
                AuthorityUtils.createAuthorityList("ROLE_ADMIN")
        ));
    }
}

Context

I'm building a non-web application. I use Spring Security to protect my methods outside the web servlet context. I need to catch UsernameNotFoundException intead of BadCredentialsException.

DaoAuthenticationProvider is created in this place:

@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
String[] beanNames = InitializeUserDetailsBeanManagerConfigurer.this.context
.getBeanNamesForType(UserDetailsService.class);
if (auth.isConfigured()) {
if (beanNames.length > 0) {
this.logger.warn("Global AuthenticationManager configured with an AuthenticationProvider bean. "
+ "UserDetailsService beans will not be used by Spring Security for automatically configuring username/password login. "
+ "Consider removing the AuthenticationProvider bean. "
+ "Alternatively, consider using the UserDetailsService in a manually instantiated DaoAuthenticationProvider. "
+ "If the current configuration is intentional, to turn off this warning, "
+ "increase the logging level of 'org.springframework.security.config.annotation.authentication.configuration.InitializeUserDetailsBeanManagerConfigurer' to ERROR");
}
return;
}
if (beanNames.length == 0) {
return;
}
else if (beanNames.length > 1) {
this.logger.warn(LogMessage.format("Found %s UserDetailsService beans, with names %s. "
+ "Global Authentication Manager will not use a UserDetailsService for username/password login. "
+ "Consider publishing a single UserDetailsService bean.", beanNames.length,
Arrays.toString(beanNames)));
return;
}
UserDetailsService userDetailsService = InitializeUserDetailsBeanManagerConfigurer.this.context
.getBean(beanNames[0], UserDetailsService.class);
PasswordEncoder passwordEncoder = getBeanOrNull(PasswordEncoder.class);
UserDetailsPasswordService passwordManager = getBeanOrNull(UserDetailsPasswordService.class);
CompromisedPasswordChecker passwordChecker = getBeanOrNull(CompromisedPasswordChecker.class);
DaoAuthenticationProvider provider = new DaoAuthenticationProvider(userDetailsService);
if (passwordEncoder != null) {
provider.setPasswordEncoder(passwordEncoder);
}
if (passwordManager != null) {
provider.setUserDetailsPasswordService(passwordManager);
}
if (passwordChecker != null) {
provider.setCompromisedPasswordChecker(passwordChecker);
}
provider.afterPropertiesSet();
auth.authenticationProvider(provider);
this.logger.info(LogMessage.format(
"Global AuthenticationManager configured with UserDetailsService bean with name %s", beanNames[0]));
}

DaoAuthenticationProvider appears to be a local variable with explicit constructor call. So there's no chance to call DaoAuthenticationProvider.setHideUserNotFoundExceptions at this stage.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions