I'd like to hide UsernameNotFoundException in PreAuthenticatedAuthenticationProvider as like DaoAuthenticationProvider

Since I don't want to imply that the "username" doesn't exist through the class name itself, let alone the error message.

--

hideUserNotFoundExceptions is allowed in AbstractUserDetailsAuthenticationProvider which is inherited by DaoAuthenticationProvider.

  • https://github.com/spring-projects/spring-security/blob/6.3.1/core/src/main/java/org/springframework/security/authentication/dao/AbstractUserDetailsAuthenticationProvider.java#L88

--

PreAuthenticatedAuthenticationProvider , which I'd like to use in my case, indicates UsernameNotFoundException might be thrown depends on its usage. In actual, AuthenticationUserDetailsService#loadUserDetails is able to throw UsernameNotFoundException. But the class does not support any sort of hideUserNotFoundExceptions.

  • https://github.com/spring-projects/spring-security/blob/6.3.1/web/src/main/java/org/springframework/security/web/authentication/preauth/PreAuthenticatedAuthenticationProvider.java#L43-L45

--

My current alternatives/workarounds:

Currently it seems the class can handle UsernameNotFoundException as AuthenticationException,

  • https://github.com/spring-projects/spring-security/blob/6.3.1/web/src/main/java/org/springframework/security/web/authentication/preauth/PreAuthenticatedAuthenticationProvider.java#L77

So I create and use new Exception class which inherits AuthenticationException to avoid exposure of "Username"NotFoundException in case the exception is thrown.

public class SampleUserDetailsService
        implements AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken> {
    @Override
    public UserDetails loadUserDetails(PreAuthenticatedAuthenticationToken token) {
        return Optional.ofNullable(token)
                       .map( /* normal case */ )
                       }).orElseThrow(() -> new SampleAuthenticationException());
    }

    private static class SampleAuthenticationException extends AuthenticationException {
        private SampleAuthenticationException() {
            super( /* any safe message */ );
        }
    }
}

This works, but I'm curious why PreAuthenticatedAuthenticationProvider does not support hideUserNotFoundExceptions as like AbstractUserDetailsAuthenticationProvider.

Thanks.

Comment From: jzheaux

I believe the reason is that the perspective changed over time on how applications would expose exceptions to the end user. It was also common at that time for exception messages to be translated into multiple languages for the same reason. Neither of these is a common case anymore.

That said, can you tell me what you are trying to do and why the propagation of UserNameNotFoundException is problematic in your case?

Comment From: b1ueskydragon

@jzheaux Thank you for reply. Yes, basically I agree with your opinion.

Let me just explain the background about the issue.

It all started when I override to use #loadUserDetails and throw accompanying UserNameNotFoundException straightforwardly, then I got advice from sonarqube and I think It's on point. However, It doesn't stop to advise until I stop throwing UserNameNotFoundException even I change the String message, and I consider the reason is, the class name UserName.... itself might be considered not-safe. As the result I gave up to throw UserNameNotFoundException, use the unique exception which extends AuthenticationException instead, and it's fine,

However I'm wondering is there any simple way to control it more easily as the AuthenticationProvider level.

--

image1 image0

Comment From: jzheaux

Would adapting the exception get rid of the Sonar error? It seems like Sonar is complaining because you are throwing UsernameNotFoundException. Even if the surrounding AuthenticationProvider did adapt it, it wouldn't resolve the Sonar error. It seems like the change Sonar wants you to make is to throw something else instead (like BadCredentialsException).

So, as far as I can tell, the new flag wouldn't help you. Am I missing something?

Comment From: spring-projects-issues

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

Comment From: b1ueskydragon

@jzheaux

Actually, using alternative exception class inherits AuthenticationException(e.g. SampleAuthenticationException mentioned in my main text OR BadCredentialsException introduced in your commend) had solved the sonar complaint.

With that in mind, I was just wondering if the sonar complain could be handled by other recommended practices, or other new methods, as like spring-security setting level.

However, I've got your point : The name of class UsernameNotFoundException itself has no problem, and just using alternative exceptions according to the scene, which I actually conducted, is enough and really fine.

If my understanding is correct, everything is fine.